概要
一つの画面に複数のpickerViewを定義したい際に、pickerViewのdelegateとdatasourceを定義していくとViewControllerが肥大化してしまうので、TextFieldとPickerViewを継承して、Componentを作成してみました。
※swift初めて間もないので、指摘アドバイスなどあればお願いします。
ソース
構成と役割
-
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)
}
}