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画面外す
    }
}

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()
}