LoginSignup
62
50

More than 5 years have passed since last update.

Swiftでテキストフィールドにピッカーを設定しリスト選択する(コンボボックス的な)

Last updated at Posted at 2016-12-05

Swift3.0 + Xcode8.1での実装です。

概要

こういうの。

スクリーンショット 2016-12-02 17.53.31.png

テキストフィールドをタップすると、下にピッカーが表示される。
コンボボックス的なイメージです。

Xcode(8.1)の標準コンポーネントにはこういうのはないので(ないよね?)、しこしこ実装します。

StoryBoard

まずはStoryBoardにText Filedを配置して、ViewControllerにOutlet接続しておきます。

こんな状態。
スクリーンショット 2016-12-05 10.17.17.png

ViewController

以下、ソース全体。

ViewController.swift
import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var textField: UITextField!

    var pickerView: UIPickerView = UIPickerView()
    let list = ["", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]

    override func viewDidLoad() {
        super.viewDidLoad()

        pickerView.delegate = self
        pickerView.dataSource = self
        pickerView.showsSelectionIndicator = true

        let toolbar = UIToolbar(frame: CGRectMake(0, 0, 0, 35))
        let doneItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(ViewController.done))
        let cancelItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(ViewController.cancel))
        toolbar.setItems([cancelItem, doneItem], animated: true)

        self.textField.inputView = pickerView
        self.textField.inputAccessoryView = toolbar
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

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

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

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

    func cancel() {
        self.textField.text = ""
        self.textField.endEditing(true)
    }

    func done() {
        self.textField.endEditing(true)
    }

    func CGRectMake(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) -> CGRect {
        return CGRect(x: x, y: y, width: width, height: height)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

ちょっと説明。

クラスは、UIPickerViewDelegate と UIPickerViewDataSource を継承する必要があります。

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

継承すると、以下の3つの関数を実装する必要があります。
実装するまでエラーが出ます。

func numberOfComponents(in pickerView: UIPickerView) -> Int
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?

またSwift3.0からは、CGRectMakeという、座標を指定する関数が使えなくなっているので、自分でWrapする関数を作っておきます。

func CGRectMake(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) -> CGRect {
    return CGRect(x: x, y: y, width: width, height: height)
}

必須選択にしたい場合

選択リストから空白を除く。

//let list = ["", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
let list = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]

Cancelをタップするとクリアするようにしているので、Cancel自体なくす。

let toolbar = UIToolbar(frame: CGRectMake(0, 0, 0, 35))
let doneItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(ViewController.done))
//let cancelItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(ViewController.cancel))
//toolbar.setItems([cancelItem, doneItem], animated: true)
toolbar.setItems([doneItem], animated: true)

viewDidLoad()で初期値を設定する。

self.textField.text = list[0]

ってすれば必須になると思います。

スクリーンショット 2016-12-05 10.41.02.png

62
50
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62
50