1.はじめに
以前、【Swift】キーボードにUIPickerViewを表示するという記事を投稿しました。
これをちょっとだけ応用してUITextField
とUIDatePicker
を使った日付選択のUIを作りました。
やる事は上記の記事と同様です。UITextField
のinputView
に UIDatePicker
を設定し、inputAccessoryView
に完了ボタンや今日の日付に設定するボタンを配置したツールバーを設定します。
2.環境
Xcode Version 9.4.1
Swift Version 4.1.2
3.完成形
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をcanPerformAction
、selectionRects
、caretRect
で無効にしています。
・UIDatePicker
で日付を変更するたびにUITextField
の値を変更させるためにdatePicker.addTarget(self, action: #selector(setText), for: .valueChanged)
を初期化時に行います。
・UIDatePicker
の設定やカスタマイズはお好みで。
・ツールバーの「今日」ボタンを押下した時にdatePicker.date
にDate()
を設定し、ピッカーの値を現在日時に変更します。