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

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

##出来上がり
![image.png](https://qiita-image-store.s3.amazonaws.com/0/237101/51ace9e5-10a3-c132-4929-7a1ccd00b6a0.png)

## ソース
https://github.com/kyosyun/swiftSample/tree/master/PickerSample

## 構成と役割
![image.png](https://qiita-image-store.s3.amazonaws.com/0/237101/a4f43085-fbd9-0dc8-0aa1-a1bb5d99f902.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)
    }
}
```