LoginSignup
23
20

More than 5 years have passed since last update.

年と月だけのDatePickerを作る

Last updated at Posted at 2015-11-29

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

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

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

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

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

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を開いたら閉じれなくなってしまうので、キーボードに「完了」ボタンを付けて閉じれるようにする。

UITextFieldinputAccessoryViewに、「完了」ボタンを含むUIViewをセット。

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を閉じることができるようになる。

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

Simulator Screen Shot 2015.11.29 21.07.24.png

23
20
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
23
20