iOS 8 自定义键盘:更改高度而不发出警告“无法同时满足约束...”
Posted
技术标签:
【中文标题】iOS 8 自定义键盘:更改高度而不发出警告“无法同时满足约束...”【英文标题】:iOS 8 Custom Keyboard: Changing the height without warning 'Unable to simultaneously satisfy constraints...' 【发布时间】:2014-10-26 03:20:22 【问题描述】:关于如何更改自定义键盘高度有几个 SO 答案。其中一些工作例如here,但那些工作导致约束冲突错误打印到控制台输出:
Unable to simultaneously satisfy constraints...
Will attempt to recover by breaking constraint...
这是我设置自定义键盘高度的非常简单的键盘控制器(是 Swift):
class KeyboardViewController: UIInputViewController
private var heightConstraint: NSLayoutConstraint?
private var dummyView: UIView = UIView()
override func updateViewConstraints()
super.updateViewConstraints()
if self.view.frame.size.width == 0 || self.view.frame.size.height == 0 || heightConstraint == nil
return
inputView.removeConstraint(heightConstraint!)
heightConstraint!.constant = UIInterfaceOrientationIsLandscape(self.interfaceOrientation) ? 180 : 200
inputView.addConstraint(heightConstraint!)
override func viewDidLoad()
super.viewDidLoad()
self.dummyView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(self.dummyView)
view.addConstraint(NSLayoutConstraint(item: self.dummyView, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1.0, constant: 0.0))
view.addConstraint(NSLayoutConstraint(item: self.dummyView, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: 0.0))
heightConstraint = NSLayoutConstraint(item: view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 0.0)
这会产生烦人的输出错误,即我在 updateViewConstraints
中添加的约束 heightConstraint
与标识为 UIView-Encapsulated-Layout-Height
的约束冲突。
我尝试删除 updateViewConstraints
中的冲突常量 (UIView-Encapsulated-Layout-Height
),如下所示:
let defaultHeightConst = inputView.constraints().filter() c in (c as? NSLayoutConstraint)?.identifier == "UIView-Encapsulated-Layout-Height".first as? NSLayoutConstraint
if defaultHeightConst != nil
inputView.removeConstraint(defaultHeightConst!
这没有帮助,输出警告仍然存在。我该如何解决这个问题?具体来说,我该怎么做才能摆脱输出的错误信息?
【问题讨论】:
你摆脱了输出警告??? @Ezimet 是的,不出所料,我摆脱了输出警告。非常令人惊讶的是,优先级为 990 的常量仍然不会被更高优先级的默认高度常量(之前与之冲突)覆盖。愿意解释一下为什么对我来说是这样吗? 【参考方案1】:尝试将 heightConstraint 的优先级设置为小于 1000。例如 blow :
heightConstraint.priority = 990
或
heightConstraint.priority = 999
【讨论】:
heightConstraint = 990
选项确实有效,heightConstraint = UILayoutPriorityDefaultHigh
不会编译。
编辑了我的答案。实际上优先级 999 或 990 都适合你。这些优先级几乎与 1000 要求的优先级一样高,因此它们不会轻易受到影响。
当我设置这个时我的应用程序崩溃:(
如果你这样做,那么你的约束将不会被考虑在内,因为它的优先级将低于自动生成的。即使作者告诉它有效,但它对我不起作用——我无法解释为什么它对他有效……【参考方案2】:
此警告在 ios 13 中仍然存在问题。
之所以出现是因为键盘扩展的视图(KeyboardViewController
的view
属性)将自动调整掩码转换为约束。
你想要的是通过调用移除自动生成的高度约束:
view.translatesAutoresizingMaskIntoConstraints = false
然而,这还不够:您必须替换重要的生成约束。
我在viewWillAppear
函数中这样做了,因为此时父视图存在。我使用constraintHaveBeenAdded
属性来避免多次添加相同的约束,因为该函数可以重复调用。
class KeyboardViewController: UIInputViewController
private var constraintsHaveBeenAdded = false
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
initKeyboardConstraints()
private func initKeyboardConstraints()
if constraintsHaveBeenAdded return
guard let superview = view.superview else return
view.translatesAutoresizingMaskIntoConstraints = false
view.leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true
view.rightAnchor.constraint(equalTo: superview.rightAnchor).isActive = true
view.heightAnchor.constraint(equalToConstant: 250.0).isActive = true
constraintsHaveBeenAdded = true
您甚至可以移除高度约束,让子视图约束决定键盘高度。
【讨论】:
以上是关于iOS 8 自定义键盘:更改高度而不发出警告“无法同时满足约束...”的主要内容,如果未能解决你的问题,请参考以下文章