2019年11月26日火曜日

UITextField の入力に pickerView を設定する方法

概要

UITextField はデフォルトだとキーボードからの入力を受け付けます
セレクトボックスの用に入力する項目が決まっている場合は pickerView を入力に設定することができます

環境

  • macOS 10.15.1
  • Xcode 11.2.1 (11B500)

UITextField を設置する

まずは StoryBoard を使って UITextField を設置します
コンポーネントは右上の「+」ボタンから設置することができます

場所はどこでもいいです
確認のために UILabel も 1 つ設置しています

ViewController と接続する

IBOutlet を使ってコードと UI を紐付けましょう
StoryBoard の右上から「Assistant」を選択します

すると StoryBoard に紐づく ViewController が表示されるので Ctrl を押しながら各種 UI コンポーネントをコードに紐付けましょう

UIPickerViewDelegate を実装する

次に pickerView を作成します
pickerView のイベントをコントロールするために UIPickerViewDelegate, UIPickerViewDataSource を実装しましょう

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return 3
    }

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var result: UILabel!
    var pickerView = UIPickerView()

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

numberOfComponents は pickerView に表示する列の数です
numberOfRowsInComponent は pickerView に表示するデータの数です
今回は 3 つのデータを pickerView に表示して選択できるようにします

pickerView を UITextField の入力に設定する

UITextField を選択したときに pickerView のキーボードが表示されるようにします
今回は createPickerView というメソッドを準備しました

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return 3
    }

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var result: UILabel!
    var pickerView = UIPickerView()

    override func viewDidLoad() {
        super.viewDidLoad()
        createPickerView()
    }

    func createPickerView() {
        pickerView.delegate = self
        textField.inputView = pickerView
        // toolbar
        let toolbar = UIToolbar()
        toolbar.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 44)
        let doneButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(ViewController.donePicker))
        toolbar.setItems([doneButtonItem], animated: true)
        textField.inputAccessoryView = toolbar
    }

    @objc func donePicker() {
        textField.endEditing(true)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textField.endEditing(true)
    }
}

ポイントは textField.inputView = pickerView の部分で UITextField が持つ inputView に pickerView を設定します
こうすることで入力のキーボードを pickerView にすることができます
今回はおまけで UIToolbar も設置しています
これは必須ではないですが UX 的にはあって良いかなと思います
今回は toolbar 上のボタンを押すかキーボード以外の場所をタップしたときにキーボードを非表示にしています

イベントの実装

あとは pickerView のデータを選択したときのイベントを実装します
最低限実装するのは titleForRowdidSelectRow です
titleForRow は pickerView に設定するデータを登録するためのメソッドです
didSelectRow は pickerView の各種データを選択したときに呼ばれるメソッドです
今回はここで UITextField と確認用の UILabel に選択されたデータを表示するようにしています

また pickerView に表示するデータは固定の配列データにしています

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return 3
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return data[row]
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        textField.text = data[row]
        result.text = data[row]
    }

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var result: UILabel!
    var pickerView = UIPickerView()
    var data = ["Orange", "Grape", "Banana"]

    override func viewDidLoad() {
        super.viewDidLoad()
        createPickerView()
    }

    func createPickerView() {
        pickerView.delegate = self
        textField.inputView = pickerView
        // toolbar
        let toolbar = UIToolbar()
        toolbar.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 44)
        let doneButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(ViewController.donePicker))
        toolbar.setItems([doneButtonItem], animated: true)
        textField.inputAccessoryView = toolbar
    }

    @objc func donePicker() {
        textField.endEditing(true)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textField.endEditing(true)
    }
}

動作確認

ビルドして動作確認してみましょう

UITextField を選択すると pickerView のキーボードが表示され選択するとデータが反映されるのが確認できると思います

最後に

UITextField の入力に pickerView のキーボードを設定する方法を紹介しました
Web で言うところのセレクトボックス的に使えるかなと思います

今回は実装していませんが UITextField はキーボードからの直接入力を不可にしてもいいかもしれません

0 件のコメント:

コメントを投稿