年と月だけのDatePickerを作る

DatePickerを作るには通常`UIDatePicker`を利用するが、`UIDatePickerMode`に年と月だけのピッカーはない。`UIPickerView`を利用して実装する。実行環境はXcode7.1.1。

StoryBoardで指定したViewControllerに、`UIPickerViewDelegate`と`UIPickerViewDataSource`を継承する。`UITableView`と実装の方法は似ている。

* `viewDidLoad()`において、`UITextField`の`inputView`に`UIPickerView`をセット、`delegate`で処理を委譲
* `numberOfComponentsInPickerView(_:)`で`UIPickerView`の要素数 (Component) を設定
  * 今回のケースでは「年」と「月」の2つ
* `pickerView(_:numberOfRowsInComponent:)`で`UIPickerView`のComponentごとのrowの数を設定
  * 「年」は1965 ~ 2015、「月」は1 ~ 12
* `pickerView(_:titleForRow:forComponent:)`で各Componentの各rowのタイトル名を設定

これで年と月のDatePickerの見た目ができる。
さらに、DatePickerのピッカーを選択した時に`UITextField`の`text`に値が自動で入るよう、`pickerView(_:didSelectRow:inComponent:)`に処理を追加。`selectedRowInComponent`で指定したインデックスのComponentで選択した値を取得できるので、それを挿入。

これまでの内容をコードにすると、以下のようになる。

```swift:ViewController.swift
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
    var textField = UITextField()
    
    let years = (1965...2015).map { $0 }
    let months = (1...12).map { $0 }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        textField = UITextField(frame: CGRectMake(50, 100, view.bounds.size.width - 50 * 2, 36))
        textField.borderStyle = .Line
        
        let pickerView = UIPickerView()
        pickerView.backgroundColor = UIColor.whiteColor()
        pickerView.delegate = self
        textField.inputView = pickerView        
        view.addSubview(textField)
    }
    
    // MARK: - UIPickerView data source
    
    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 2
    }

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if component == 0 {
            return years.count
        } else if component == 1 {
            return months.count
        } else {
            return 0
        }
    }
    
    // MARK: - UIPickerView delegate
    
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if component == 0 {
            return "\(years[row])年"
        } else if component == 1 {
            return "\(months[row])月"
        } else {
            return nil
        }
    }
    
    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        let year = years[pickerView.selectedRowInComponent(0)]
        let month = months[pickerView.selectedRowInComponent(1)]
        textField.text = "\(year)年 \(month)月"
    }
    
}
```

これだけだと、一度DatePickerを開いたら閉じれなくなってしまうので、キーボードに「完了」ボタンを付けて閉じれるようにする。

`UITextField`の`inputAccessoryView`に、「完了」ボタンを含む`UIView`をセット。

```swift:ViewController.swift
func setKeyboardAccessory() {
    let keyboardAccessory = UIView(frame: CGRectMake(0, 0, view.bounds.size.width, 36))
    keyboardAccessory.backgroundColor = UIColor.whiteColor()
    textField.inputAccessoryView = keyboardAccessory
    
    let topBorder = UIView(frame: CGRectMake(0, 0, keyboardAccessory.bounds.size.width, 0.5))
    topBorder.backgroundColor = UIColor.lightGrayColor()
    keyboardAccessory.addSubview(topBorder)
    
    let completeButton = UIButton(frame: CGRectMake(keyboardAccessory.bounds.size.width - 48, 0, 48, keyboardAccessory.bounds.size.height - 0.5 * 2))
    completeButton.titleLabel?.font = UIFont.boldSystemFontOfSize(16.0)
    completeButton.setTitle("完了", forState: .Normal)
    completeButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
    completeButton.setTitleColor(UIColor.redColor(), forState: .Highlighted)
    completeButton.addTarget(self, action: "hidePickerView", forControlEvents: .TouchUpInside)
    keyboardAccessory.addSubview(completeButton)
    
    let bottomBorder = UIView(frame: CGRectMake(0, keyboardAccessory.bounds.size.height - 0.5, keyboardAccessory.bounds.size.width, 0.5))
    bottomBorder.backgroundColor = UIColor.lightGrayColor()
    keyboardAccessory.addSubview(bottomBorder)
}

func hidePickerView() {
    textField.resignFirstResponder()
}
```

上記のコードを`ViewController.swift`に追加し、`viewDidLoad`の中で`setKeyboardAccessory()`メソッドを呼び出すようにするとキーボードに「完了」ボタンが付き、DatePickerを閉じることができるようになる。

下のスクショのようなのができる。

<img width="375" alt="Simulator Screen Shot 2015.11.29 21.07.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/1795/db48f684-465a-9606-de7f-faecdd119d49.png">