29
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Swift】キーボードにUIDatePickerを表示する

Last updated at Posted at 2018-09-16

1.はじめに

 以前、【Swift】キーボードにUIPickerViewを表示するという記事を投稿しました。
 これをちょっとだけ応用してUITextFieldUIDatePicker を使った日付選択のUIを作りました。
 やる事は上記の記事と同様です。UITextFieldinputViewUIDatePicker を設定し、inputAccessoryView に完了ボタンや今日の日付に設定するボタンを配置したツールバーを設定します。

2.環境

Xcode Version 9.4.1
Swift Version 4.1.2

3.完成形

Simulator Screen Shot - iPhone X - 2018-09-16 at 17.31.40.png

4.コード全体

class DatePickerKeyboard: UITextField {
    private var datePicker: UIDatePicker!

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commoninit()
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        commoninit()
    }
    private func commoninit() {
        // datePickerの設定
        datePicker = UIDatePicker()
        datePicker.date = Date()
        datePicker.datePickerMode = .date
        datePicker.locale = Locale(identifier: "ja")
        datePicker.addTarget(self, action: #selector(setText), for: .valueChanged)

        // textFieldのtextに日付を表示する
        setText()

        inputView = datePicker
        inputAccessoryView = createToolbar()
    }

    // キーボードのアクセサリービューを作成する
    private func createToolbar() -> UIToolbar {
        let toolbar = UIToolbar()
        toolbar.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: 44)

        let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: self, action: nil)
        space.width = 12
        let flexSpaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
        let todayButtonItem = UIBarButtonItem(title: "今日", style: .done, target: self, action: #selector(todayPicker))
        let doneButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePicker))

        let toolbarItems = [flexSpaceItem, todayButtonItem, doneButtonItem, space]

        toolbar.setItems(toolbarItems, animated: true)

        return toolbar
    }

    // キーボードの完了ボタンタップ時に呼ばれる
    @objc private func donePicker() {
        resignFirstResponder()
    }
    // キーボードの今日ボタンタップ時に呼ばれる
    @objc private func todayPicker() {
        datePicker.date = Date()
        setText()
    }

    // datePickerの日付けをtextFieldのtextに反映させる
    @objc private func setText() {
        let f = DateFormatter()
        f.dateStyle = .long
        f.locale = Locale(identifier: "ja")
        text = f.string(from: datePicker.date)
    }

    // クラス外から日付を取り出すためのメソッド
    func getDate() -> Date {
        return datePicker.date
    }

    // コピペ等禁止
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return false
    }
    // 選択禁止
    override func selectionRects(for range: UITextRange) -> [Any] {
        return []
    }
    // カーソル非表示
    override func caretRect(for position: UITextPosition) -> CGRect {
        return CGRect(x: 0, y: 0, width: 0, height: 0)
    }
}

5.ポイント

UITextField のサブクラスを作成します。
UIDatePicker 以外でUITextField の値を変更させたくないので、通常のキーボード入力時に表示されるカーソルやコピペ用のUIをcanPerformActionselectionRectscaretRect で無効にしています。
UIDatePicker で日付を変更するたびにUITextField の値を変更させるためにdatePicker.addTarget(self, action: #selector(setText), for: .valueChanged) を初期化時に行います。
UIDatePicker の設定やカスタマイズはお好みで。
・ツールバーの「今日」ボタンを押下した時にdatePicker.dateDate() を設定し、ピッカーの値を現在日時に変更します。

29
31
2

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
29
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?