import UIKit import SafariServices extension UIViewController { func presentSafariVC(with url: URL) { let safariVC = SFSafariViewController(url: url) present(safariVC, animated: true) } }
ViewControllerに更にViewControllerを追加する
func add(childViewController: UIViewController, to containerView: UIView) { self.addChild(childViewController) containerView.addSubview(childViewController.view) childViewController.view.frame = containerView.bounds childViewController.didMove(toParent: self) }
Loading画面の表示
UIViewControllerにshowLoadingViewとdismissLoadingViewという二つFunctionを拡張する。
import UIKit fileprivate var loadingView: UIView! extension UIViewController { func showLoadingView() { loadingView = UIView(frame: view.bounds) view.addSubview(loadingView) loadingView.backgroundColor = .systemBackground loadingView.alpha = 0 UIView.animate(withDuration: 0.24) { loadingView.alpha = 0.8 } let activityIndicator = UIActivityIndicatorView(style: .large) loadingView.addSubview(activityIndicator) activityIndicator.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ activityIndicator.centerYAnchor.constraint(equalTo: loadingView.centerYAnchor), activityIndicator.centerXAnchor.constraint(equalTo: loadingView.centerXAnchor) ]) activityIndicator.startAnimating() } func dismissLoadingView() { loadingView.removeFromSuperview() loadingView = nil } }
使用例:ViewController起動時Loading画面を表示、重いデータ取得処理終了後Loading画面外す。
class ChartViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() ... // 他の初期処理 showLoadingView() // Loading画面表示 } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) ... // 重いデータ取得処理 dismissLoadingView() // Loading画面外す } }
for ... in文の中にインデックスを取得する方法
for (index, player) in players.enumerated() { ... }
UIPickerViewで入力内容を選択
例:テキストボックスtxtPlayerをクリックすると、UIPickerViewが表示される。「完了」ボタンを押すと選択された内容がテキストボックスに表示される。
class PlayerViewController: UIViewController { @IBOutlet var txtPlayer: UITextField! let pickerView = UIPickerView() let players = ["Mark", "Peter", "Jack"] override func viewDidLoad() { super.viewDidLoad() // set pickerView pickerView.delegate = self pickerView.dataSource = self let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 35)) let spacelItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil) let doneItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(afterPickPlayer)) toolbar.setItems([spacelItem, doneItem], animated: true) txtPlayer.inputView = pickerView txtPlayer.inputAccessoryView = toolbar } @objc func afterPickPlayer() { txtPlayer.endEditing(true) txtPlayer.text = "\(players[pickerView.selectedRow(inComponent: 0)].name)" } } extension PlayerViewController: UIPickerViewDelegate, UIPickerViewDataSource { func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return players.count } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return players[row].name } }
Macbookで他社マウスを使う時スクロール方向設定法
Mac自分の設定メニューに、マウスのスクロール方向設定のオプションがあるが、設定するとTrackpadの方向は逆になってしまった。幸い、ネットでScroll Reverserというアプリを発見した。それを使うと、マウスだけのスクロール方向が調整できる。
Scroll Reverserインストール後、最初開く時、「アクセシビリティ」と「入力監視」という二つの権限を要求する。それぞれチェックしてからうまく作動できる。
Notification送信と受信
サンプル:送信側は受信側にテーブルリロードを要求する。
Notification名前定義:
extension NSNotification.Name { static let reload = Self.init("reload") }
送信側:
NotificationCenter.default.post(name: .reload, object: nil)
受信側:
override func viewDidLoad() { ... NotificationCenter.default.addObserver(self, selector: #selector(reload), name: .reload, object: nil) } @objc func reload() { self.tableView.reloadData() }