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で選択した値を取得できるので、それを挿入。
これまでの内容をコードにすると、以下のようになる。
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
をセット。
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を閉じることができるようになる。
下のスクショのようなのができる。