无法同时满足约束 iOS

Posted

技术标签:

【中文标题】无法同时满足约束 iOS【英文标题】:Unable to simultaneously satisfy constraints iOS 【发布时间】:2020-04-01 16:46:37 【问题描述】:

我有一个限制在视图底部的按钮。 该按钮最初是隐藏的,直到点击表格视图中的项目。 表格有一个搜索控制器,当点击它时,我希望使按钮移动,使其始终位于键盘上方。

    @objc func keyboardWillShow(notification: NSNotification) 
        if let keyboardHeight = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.height 

            startAssessmentBtn.snp.makeConstraints  make in
                make.bottom.equalTo(-keyboardHeight)
            

            let userInfo = notification.userInfo! as [AnyHashable: Any]
            let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber
            let animationCurve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as! NSNumber

            UIView.setAnimationCurve(UIView.AnimationCurve(rawValue: animationCurve.intValue)!)
            UIView.animate(withDuration: animationDuration.doubleValue) 
                self.tableView.setBottomInset(to: keyboardHeight)
                self.view.layoutIfNeeded()
            
        
    

    @objc func keyboardDidHide(notification: NSNotification) 
        if let keyboardHeight = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue 

            let userInfo = notification.userInfo! as [AnyHashable: Any]
            let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber
            let animationCurve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as! NSNumber

            startAssessmentBtn.snp.makeConstraints  make in
                make.bottom.equalTo(0)
                //make.bottom.equalToSuperview()//.offset(+keyboardHeight)
            

            UIView.setAnimationCurve(UIView.AnimationCurve(rawValue: animationCurve.intValue)!)
            UIView.animate(withDuration: animationDuration.doubleValue) 
                self.tableView.setBottomInset(to: 0.0)
                self.startAssessmentBtn.setNeedsLayout()
                self.startAssessmentBtn.layoutIfNeeded()
                self.view.layoutIfNeeded()
            
        
    

使用上面的代码,我可以在第一次打开键盘时让按钮出现在键盘上方。但是当键盘关闭时,按钮不会返回到屏幕底部。我收到以下约束错误:

2020-04-01 17:38:42.629598+0100 AuditComply 2.0[4550:3372130] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<SnapKit.LayoutConstraint:0x2830057a0@AssetTreeViewController.swift#126 UIButton:0x121deacd0.bottom == UIView:0x121deb100.bottom - 320.0>",
    "<SnapKit.LayoutConstraint:0x283005620@AssetTreeViewController.swift#149 UIButton:0x121deacd0.bottom == UIView:0x121deb100.bottom>"
)

Will attempt to recover by breaking constraint 
<SnapKit.LayoutConstraint:0x283005620@AssetTreeViewController.swift#149 UIButton:0x121deacd0.bottom == UIView:0x121deb100.bottom>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

因此,keyboardWillShow 的约束似乎覆盖了keyboardDidHide 的约束。我已经尝试更改约束的优先级,但这也不起作用。

【问题讨论】:

在你分配新的约束之前,你应该删除它之前的。 【参考方案1】:

很明显,您正在使用 SnapKit。 makeConstraints 为现有约束添加约束。

要更新现有约束,您应该使用updateConstraints,但您应该锚定到同一点,

例如:.equalToSuperview().inset(0).equalToSuperview().inset(keyboardHeight)

如果没有锚定到同一点的选项,您应该清除以前的约束并创建一些新的约束。您可以使用 .remakeConstraints 同时执行此操作,但您应该添加所有其他约束,例如前导、尾随、顶部

【讨论】:

以上是关于无法同时满足约束 iOS的主要内容,如果未能解决你的问题,请参考以下文章

iOS 11:“无法同时满足约束”

无法同时满足约束 iOS

iOS:在 segue 中无法同时满足约束

如果设置隐藏,iOS UIStackView 无法同时满足约束

iOS 8 自定义键盘:更改高度而不发出警告“无法同时满足约束...”

无法使用 uiimageview 同时满足 uitableviewcell 中的约束