LoginSignup
3
2

More than 5 years have passed since last update.

TextFieldを押下時に下からPickerViewを出すコンポーネント作成をしてみた

Last updated at Posted at 2018-04-16

概要

一つの画面に複数のpickerViewを定義したい際に、pickerViewのdelegateとdatasourceを定義していくとViewControllerが肥大化してしまうので、TextFieldとPickerViewを継承して、Componentを作成してみました。
※swift初めて間もないので、指摘アドバイスなどあればお願いします。

出来上がり

image.png

ソース

構成と役割

image.png

  • ViewController  
    TextFieldPickerViewの呼び出し

  • WeekTextPickerView
    TextFieldとPickerViewの紐付けを実施

  • WeekPickerView  
    pickerの中身の定義を実施。datasorceを定義。

  • TextFieldPickerView
    pickerViewを表示用のToolBarの生成を共通として用意

  • UIViewController
    ToolBarの完了時の動作を一箇所で定義

詳細

ViewController

呼び出しもと

@IBOutlet weak var weekTextField: WeekTextFieldPickerView!

WeekTextPickerView

pickerViewとTextFieldの紐付けを実施

import UIKit

class WeekTextFieldPickerView: TextFieldPickerView {

    //pickerの定義を行う(UIPickerViewを継承したもの)
    let weekPickerView = WeekPickerView()

    //delegateの宣言を行う
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        weekPickerView.weekPickerViewDelegate = self
        self.inputView = weekPickerView.getInputView()
    }
}

extension WeekTextFieldPickerView: WeekPickerViewDelegate {
    //pickerを選択した際の動作 responseに利用する値はここで定義する
    func setValueToTextField(day: String) {
        self.text = day
        self.responseVal = day
    }
}

WeekPickerView

PickerのDatasorceの定義をする。

import UIKit

class WeekPickerView: UIPickerView {

    weak var weekPickerViewDelegate: WeekPickerViewDelegate?

    var week = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]

    init() {
        super.init(frame: CGRect())
        self.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height:self.bounds.size.height)
        self.dataSource = self
        self.delegate = self
        let weekVi = UIView(frame: self.bounds)
        weekVi.backgroundColor = UIColor.white
        weekVi.addSubview(self)
    }

    func getInputView() -> UIView {
        let weekVi = UIView(frame: self.bounds)
        weekVi.backgroundColor = UIColor.white
        weekVi.addSubview(self)
        return weekVi
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

}

extension WeekPickerView: UIPickerViewDelegate {
    //pickerの選択時の動作
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        weekPickerViewDelegate?.setValueToTextField(day: week[row])
    }

}

protocol WeekPickerViewDelegate: class {
    func setValueToTextField(day: String)
}

extension WeekPickerView: UIPickerViewDataSource {

    //pickerのコンポーネント数
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    //pickerの中身の表示
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return week[row]
    }

    //pickerのlistの数
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return week.count
    }
}

TextFieldPickerView

ToolBarの生成。TextFieldの共通のコンポネーントとして生成。
継承して利用する。

import UIKit

class TextFieldPickerView: UITextField {

    var responseVal: String?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.inputAccessoryView = createToolBar()
    }

    func createToolBar() -> UIView {
        let toolBar = UIToolbar()
        toolBar.barStyle = UIBarStyle.default
        toolBar.isTranslucent = true
        toolBar.tintColor = UIColor.black

        let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: UIViewController(), action: #selector(
            UIViewController.endiEditing))

        let spaceButton  = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)

        toolBar.setItems([spaceButton, doneButton], animated: false)
        toolBar.isUserInteractionEnabled = true
        toolBar.sizeToFit()
        return toolBar
    }
}

UIViewController

toolBarの完了ボタン押下時の動作を共通で定義。

import UIKit

extension UIViewController {
    @objc func endiEditing() {
        view.endEditing(true)
    }
}
3
2
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
3
2