4
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.

高さ可変のinputViewを表示する(Swift)

Posted at

Xcode-12 Swift-5.3 iOS-14

はじめに

以前書いた下記記事でキーボードの高さもいい感じになってると思っていたのですがそうでもなかった模様:innocent:

inputAccessoryView を表示するとわかるのですがカスタムの inputView が表示領域を飛び出していた。

これをいい感じに表示したい。ついでに高さを可変にしてみます。

いろいろチャレンジ

CustomInputView っていうのを xib で作成して使用しています。
どうにか高さを設定してやればいいと思い色々試してみました。

オートレイアウト

下記のように高さの制約をつけてみましたが高さ 500 にはなりませんでした:neutral_face:(通常のキーボードと同じ高さになりました)。

let v = CustomInputView()
v.translatesAutoresizingMaskIntoConstraints = false
v.heightAnchor.constraint(equalToConstant: 500).isActive = true
textField.inputView = v

詳しくわからないですが inputView に制約を追加してもまだ add されてないから制約が効かないとかなんでしょうか:thinking:

frame設定

UIViewframe に高さを設定してみるとそれっぽい表示になりました:raised_hands:

let v = CustomInputView()
var frame = v.frame
frame.size.height = 500
v.frame = frame
textField.inputView = v

この方法でいけそう:thinking:

高さを可変にする

上記のように frame 設定で高さ調整ができました。ここからは需要があるかわかりませんが高さを可変にすることに挑戦します。

方法としては xib で Auto Layout を設定して、frame.heightsystemLayoutSizeFitting で計算した高さを設定してやればいけるはずです。

完成形:sunglasses:(とくに意味はないですがチェックボックスを並べてみました)

custom_input

ソース

protocol CustomKeyboardViewDelegate: AnyObject {
    func customKeyboardView(_ customKeyboardView: CustomKeyboardView, didToggleButton checked: CustomKeyboardView.Checked)
}

final class CustomKeyboardView: UIView {

    struct Hidden {
        let isFirst: Bool
        let isSecond: Bool
        let isThird: Bool
        let isFourth: Bool
        let isFifth: Bool
        let isSixth: Bool
    }

    struct Checked {
        let isFirst: Bool
        let isSecond: Bool
        let isThird: Bool
        let isFourth: Bool
        let isFifth: Bool
        let isSixth: Bool
    }

    @IBOutlet weak var firstButton: UIButton!
    @IBOutlet weak var secondButton: UIButton!
    @IBOutlet weak var thirdButton: UIButton!
    @IBOutlet weak var fourthButton: UIButton!
    @IBOutlet weak var fifthButton: UIButton!
    @IBOutlet weak var sixthButton: UIButton!

    weak var delegate: CustomKeyboardViewDelegate?

    func setupDefaultValue(hidden: Hidden, checked: Checked) {
        firstButton.isHidden = hidden.isFirst
        secondButton.isHidden = hidden.isSecond
        thirdButton.isHidden = hidden.isThird
        fourthButton.isHidden = hidden.isFourth
        fifthButton.isHidden = hidden.isFifth
        sixthButton.isHidden = hidden.isSixth

        firstButton.isSelected = checked.isFirst
        secondButton.isSelected = checked.isSecond
        thirdButton.isSelected = checked.isThird
        fourthButton.isSelected = checked.isFourth
        fifthButton.isSelected = checked.isFifth
        sixthButton.isSelected = checked.isSixth
    }

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

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        loadNib()
    }

    private func loadNib() {
        let view = Bundle.main.loadNibNamed("CustomKeyboardView", owner: self, options: nil)?.first as! UIView
        view.frame = bounds
        view.translatesAutoresizingMaskIntoConstraints = true
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(view)
    }

    @IBAction private func toggleButton(_ sender: UIButton) {
        sender.isSelected.toggle()
        delegate?.customKeyboardView(self, didToggleButton: .init(
            isFirst: firstButton.isSelected, isSecond: secondButton.isSelected,
            isThird: thirdButton.isSelected, isFourth: fourthButton.isSelected,
            isFifth: fifthButton.isSelected, isSixth: sixthButton.isSelected
        ))
    }
}
class FirstViewController: UIViewController {

    @IBOutlet private weak var textField: UITextField!
    private var isFirstHidden: Bool = false
    private var isSecondHidden: Bool = false
    private var isThirdHidden: Bool = false
    private var isFourthHidden: Bool = false
    private var isFifthHidden: Bool = false
    private var isSixthHidden: Bool = false

    private var isFirstChecked: Bool = false
    private var isSecondChecked: Bool = false
    private var isThirdChecked: Bool = false
    private var isFourthChecked: Bool = false
    private var isFifthChecked: Bool = false
    private var isSixthChecked: Bool = false

    override func viewDidLoad() {
        super.viewDidLoad()
        let toolbar = UIToolbar()
        toolbar.items = [
            UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil),
            UIBarButtonItem.init(title: "閉じる", style: .done, target: self, action: #selector(close))
        ]
        toolbar.sizeToFit()
        textField.inputAccessoryView = toolbar
    }

    @objc private func close() {
        textField.resignFirstResponder()
    }

    @IBAction private func pattern1(_ sender: Any) {
        textField.resignFirstResponder()
        isFirstHidden = false
        isSecondHidden = false
        isThirdHidden = false
        isFourthHidden = false
        isFifthHidden = false
        isSixthHidden = false
        setupInputView()
        textField.becomeFirstResponder()
    }

    @IBAction private func pattern2(_ sender: Any) {
        textField.resignFirstResponder()
        isFirstHidden = false
        isSecondHidden = true
        isThirdHidden = false
        isFourthHidden = true
        isFifthHidden = false
        isSixthHidden = true
        setupInputView()
        textField.becomeFirstResponder()
    }

    @IBAction private func pattern3(_ sender: Any) {
        textField.resignFirstResponder()
        isFirstHidden = false
        isSecondHidden = false
        isThirdHidden = true
        isFourthHidden = true
        isFifthHidden = true
        isSixthHidden = true
        setupInputView()
        textField.becomeFirstResponder()
    }

    private func setupInputView() {
        let view = CustomKeyboardView()
        view.delegate = self
        let hidden: CustomKeyboardView.Hidden =
            .init(isFirst: isFirstHidden, isSecond: isSecondHidden, isThird: isThirdHidden,
                  isFourth: isFourthHidden, isFifth: isFifthHidden, isSixth: isSixthHidden)
        let checked: CustomKeyboardView.Checked =
            .init(isFirst: isFirstChecked, isSecond: isSecondChecked, isThird: isThirdChecked,
                  isFourth: isFourthChecked, isFifth: isFifthChecked, isSixth: isSixthChecked)
        view.setupDefaultValue(hidden: hidden, checked: checked)
        var frame = view.frame
        frame.size.height = view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
        view.frame = frame
        textField.inputView = view
    }
}

extension FirstViewController: CustomKeyboardViewDelegate {
    func customKeyboardView(_ customKeyboardView: CustomKeyboardView, didToggleButton checked: CustomKeyboardView.Checked) {
        isFirstChecked = checked.isFirst
        isSecondChecked = checked.isSecond
        isThirdChecked = checked.isThird
        isFourthChecked = checked.isFourth
        isFifthChecked = checked.isFifth
        isSixthChecked = checked.isSixth
    }
}

高さも可変でチェック状態も引継げる inputView ができました:clap:

おわりに

使い道があるかは知りませんが無事高さ可変の inputView ができました:tada:

他にも下記のような方法があるみたいです。

4
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
4
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?