はじめに
以前書いた下記記事でキーボードの高さもいい感じになってると思っていたのですがそうでもなかった模様
inputAccessoryView
を表示するとわかるのですがカスタムの inputView
が表示領域を飛び出していた。

これをいい感じに表示したい。ついでに高さを可変にしてみます。
いろいろチャレンジ
CustomInputView
っていうのを xib で作成して使用しています。
どうにか高さを設定してやればいいと思い色々試してみました。
オートレイアウト
下記のように高さの制約をつけてみましたが高さ 500 にはなりませんでした(通常のキーボードと同じ高さになりました)。
let v = CustomInputView()
v.translatesAutoresizingMaskIntoConstraints = false
v.heightAnchor.constraint(equalToConstant: 500).isActive = true
textField.inputView = v

詳しくわからないですが inputView
に制約を追加してもまだ add されてないから制約が効かないとかなんでしょうか
frame設定
UIView
の frame
に高さを設定してみるとそれっぽい表示になりました
let v = CustomInputView()
var frame = v.frame
frame.size.height = 500
v.frame = frame
textField.inputView = v

この方法でいけそう
高さを可変にする
上記のように frame
設定で高さ調整ができました。ここからは需要があるかわかりませんが高さを可変にすることに挑戦します。
方法としては xib で Auto Layout を設定して、frame.height
に systemLayoutSizeFitting
で計算した高さを設定してやればいけるはずです。
完成形(とくに意味はないですがチェックボックスを並べてみました)
ソース
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
ができました
おわりに
使い道があるかは知りませんが無事高さ可変の inputView
ができました
他にも下記のような方法があるみたいです。