iOS Swift自定义InputView键盘高度过大设置无效问题求解
问题描述
通过.xib与.swift实现自定义数字键盘,最初通过如下代码将其设置为UITextField的inputView:
let customNumberPad = CustomNumberPad() length.inputView = customNumberPad.inputView
运行后键盘区域尺寸过大,与系统默认键盘尺寸一致,问题效果如下:
已尝试两种高度设置方案均无效:
- 在.xib中通过约束将键盘高度设为200
- 手动给inputView添加高度约束:
length.inputView!.autoresizingMask = [] let heightAnch = length.inputView!.heightAnchor.constraint(equalToConstant: 200) heightAnch.isActive = true length.reloadInputViews()
自定义键盘类完整实现代码如下:
import UIKit import AudioToolbox class CustomNumberPadSmall: UIInputViewController { @IBOutlet var numberPad: UIView! @IBAction func insertText(_ sender: UIButton) { if let text = sender.currentTitle { AudioServicesPlaySystemSound (1104) self.textDocumentProxy.insertText(text) } } @IBAction func backSpace(_ sender: UIButton) { self.textDocumentProxy.deleteBackward() } override func viewDidLoad() { super.viewDidLoad() overrideUserInterfaceStyle = USERINFO.darkModeValue Bundle.main.loadNibNamed("CustomNumberPadSmall", owner: self) numberPad.translatesAutoresizingMaskIntoConstraints = false let inputView = self.inputView! inputView.translatesAutoresizingMaskIntoConstraints = false inputView.addSubview(numberPad) NSLayoutConstraint.activate([ numberPad.topAnchor.constraint(equalTo: inputView.topAnchor), numberPad.bottomAnchor.constraint(equalTo: inputView.bottomAnchor), numberPad.leadingAnchor.constraint(equalTo: inputView.leadingAnchor), numberPad.trailingAnchor.constraint(equalTo: inputView.trailingAnchor), numberPad.heightAnchor.constraint(equalToConstant: 200) ]) } }
上述设置完成后,自定义键盘高度始终未按预期显示为200,保持系统默认大尺寸。
解决方案
问题核心原因有两点:
- 绑定键盘的方式错误:直接取
UIInputViewController的inputView属性赋值给textField的inputView,会丢失输入控制器的布局管理逻辑,系统会按默认键盘尺寸渲染 - 约束设置错误:将
inputView的translatesAutoresizingMaskIntoConstraints设为false会破坏系统对inputView的宽度适配逻辑,给子视图numberPad设置高度约束无法反向决定父视图inputView的高度,且低优先级约束会被系统默认高度约束覆盖
正确修改方式
- 第一步:修正键盘绑定逻辑,直接将自定义输入控制器实例赋值给textField的
inputViewController属性,不要手动取inputView
// 注意类名和你定义的保持一致,这里是CustomNumberPadSmall let customNumberPad = CustomNumberPadSmall() length.inputViewController = customNumberPad
- 第二步:修正自定义输入控制器内的布局代码,保留系统对inputView的宽度自适应逻辑,直接给inputView设置最高优先级的高度约束
override func viewDidLoad() { super.viewDidLoad() overrideUserInterfaceStyle = USERINFO.darkModeValue Bundle.main.loadNibNamed("CustomNumberPadSmall", owner: self) numberPad.translatesAutoresizingMaskIntoConstraints = false // 禁止修改inputView的translatesAutoresizingMaskIntoConstraints属性 inputView.addSubview(numberPad) // 子视图仅做四周边距约束,不设置高度 NSLayoutConstraint.activate([ numberPad.topAnchor.constraint(equalTo: inputView.topAnchor), numberPad.bottomAnchor.constraint(equalTo: inputView.bottomAnchor), numberPad.leadingAnchor.constraint(equalTo: inputView.leadingAnchor), numberPad.trailingAnchor.constraint(equalTo: inputView.trailingAnchor) ]) // 直接给inputView设置高度约束,优先级设为required避免被系统约束覆盖 let heightConstraint = inputView.heightAnchor.constraint(equalToConstant: 200) heightConstraint.priority = .required heightConstraint.isActive = true }
- 可选方案:如果不想使用
UIInputViewController,直接用普通UIView作为inputView,只需要自定义视图重写intrinsicContentSize属性返回目标高度即可,无需额外添加高度约束
class CustomNumberPadView: UIView { override var intrinsicContentSize: CGSize { return CGSize(width: UIView.noIntrinsicMetric, height: 200) } }
绑定方式直接将自定义视图实例赋值给textField的inputView即可。
内容的提问来源于stack exchange,提问作者WillM00
相关产品推荐
相关产品推荐

