1
2

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 3 years have passed since last update.

UITextField以外からキーボードを表示する

Posted at

UITextField以外からキーボードを表示する方法を紹介します。
以下の画像ではUIViewをカスタマイズしてUITextFieldっぽく見せています。

必須実装

UIViewに準拠した独自のViewを作成し、以下の実装を行う必要があります。

  • canBecomeFirstResponder
  • canResignFirstResponder
  • becomeFirstResponder()

ViewをタップしたタイミングでbecomeFirstResponder()を呼び出すことで、キーボードを表示することができます。

Tips

UIControlを継承することでtapイベントを取得する

UIControlではtouchUpInsideなどのイベントを取得することができるので、init時にaddTargetを呼び出しtap時の処理を登録します。
UITapGestureRecognizerなどの追加は不要です。

inputViewの設定で独自のViewをkeyboard部分に設定する

下のコードでは、UIDatePickerをinputViewに設定することで、キーボード部分で時間を設定できるようにしています。

inputAccessoryViewでkeyboardの上部のViewを設定する

下のコードでは、UIToolbarをinputAccessoryViewに設定し、ボタン押下でキーボードを閉じています。
autoresizingMaskに.flexibleHeightを指定しないと正しく表示できなかったので注意が必要です。

return押下でキーボードを閉じる

UIKeyInputに準拠することでキーボードの入力イベントを取得することができます。
returnを押した時には insertText 関数に textが "\n" として渡ってくるのでその判定の上で resignFirstResponder() を呼び出します。

コード全体

import UIKit

final class CustomInputView: UIControl {
    override var canBecomeFirstResponder: Bool { !isFirstResponder }
    override var canResignFirstResponder: Bool { isFirstResponder }
    override var inputAccessoryView: UIView? { toolbar }
    override var inputView: UIView? { datePicker }

    private lazy var toolbar: UIToolbar = {
        let toolbar = UIToolbar()
        toolbar.autoresizingMask = .flexibleHeight
        toolbar.setItems([
            UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelButtonTapped)),
            UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
            UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonTapped))
        ], animated: false)
        return toolbar
    }()

    let datePicker: UIDatePicker = {
        let picker = UIDatePicker()
        picker.datePickerMode = .countDownTimer
        picker.preferredDatePickerStyle = .wheels
        return picker
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        configure()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        configure()
    }

    private func configure() {
        addTarget(self, action: #selector(itemTapped), for: .touchUpInside)
    }

    @objc private func itemTapped() {
        if isFirstResponder {
            resignFirstResponder()
        }
        else {
            becomeFirstResponder()
        }
    }

    @objc private func cancelButtonTapped() {
        resignFirstResponder()
    }

    @objc private func doneButtonTapped() {
        resignFirstResponder()
    }
}

extension CustomInputView: UIKeyInput {
    var hasText: Bool { false }

    func insertText(_ text: String) {
        if text == "\n" {
            resignFirstResponder()
        }
    }

    func deleteBackward() {}
}
1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?