我的自动布局约束有什么问题?
What's wrong with my auto layout constraints?
这是我按下按钮之前的 UIViewController(我没有把它放在那里,因为它不相关):
当我按下按钮时,包含两个 UIPickerView 的 UIView 从顶部出现。在这个 UIView 的正下方是 2 个 UIButton。一切都适用于自动布局:
这是我创建约束时的代码:
let okButtonHeight: CGFloat = 53
let okButtonWidth: CGFloat = 53
let leftPickerViewWidth: CGFloat = 80
let leftPickerViewHeight: CGFloat = 200
let margin: CGFloat = 8
// frame
let constraint0 = NSLayoutConstraint(item: okButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
let constraint1 = NSLayoutConstraint(item: frameView, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0)
// left & right pickerViews
let constraint2 = NSLayoutConstraint(item: leftPickerView, attribute: .Width, relatedBy: .Equal, toItem: rightPickerView, attribute: .Width, multiplier: 1, constant: 0)
let constraint3 = NSLayoutConstraint(item: leftPickerView, attribute: .Height, relatedBy: .Equal, toItem: rightPickerView, attribute: .Height, multiplier: 1, constant: 0)
let constraint4 = NSLayoutConstraint(item: leftPickerView, attribute: .Trailing, relatedBy: .Equal, toItem: rightPickerView, attribute: .Leading, multiplier: 1, constant: -margin)
let constraint5 = NSLayoutConstraint(item: leftPickerView, attribute: .Top, relatedBy: .Equal, toItem: rightPickerView, attribute: .Top, multiplier: 1, constant: 0)
// left pickerView
let constraint6 = NSLayoutConstraint(item: leftPickerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: leftPickerViewHeight)
let constraint7 = NSLayoutConstraint(item: leftPickerView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: leftPickerViewWidth)
let constraint8 = NSLayoutConstraint(item: leftPickerView, attribute: .Top, relatedBy: .Equal, toItem: frameView, attribute: .Top, multiplier: 1, constant: -margin)
let constraint9 = NSLayoutConstraint(item: leftPickerView, attribute: .Bottom, relatedBy: .Equal, toItem: frameView, attribute: .Bottom, multiplier: 1, constant: margin)
let constraint10 = NSLayoutConstraint(item: leftPickerView, attribute: .Leading, relatedBy: .Equal, toItem: frameView, attribute: .Leading, multiplier: 1, constant: margin)
// right pickerView
let constraint11 = NSLayoutConstraint(item: rightPickerView, attribute: .Trailing, relatedBy: .Equal, toItem: frameView, attribute: .Trailing, multiplier: 1, constant: -margin)
// ok & cancel buttons
let constraint12 = NSLayoutConstraint(item: okButton, attribute: .Top, relatedBy: .Equal, toItem: cancelButton, attribute: .Top, multiplier: 1, constant: 0)
let constraint13 = NSLayoutConstraint(item: okButton, attribute: .Bottom, relatedBy: .Equal, toItem: cancelButton, attribute: .Bottom, multiplier: 1, constant: 0)
let constraint14 = NSLayoutConstraint(item: okButton, attribute: .Width, relatedBy: .Equal, toItem: cancelButton, attribute: .Width, multiplier: 1, constant: 0)
let constraint15 = NSLayoutConstraint(item: okButton, attribute: .Height, relatedBy: .Equal, toItem: cancelButton, attribute: .Height, multiplier: 1, constant: 0)
// ok button
let constraint16 = NSLayoutConstraint(item: view, attribute: .CenterX, relatedBy: .Equal, toItem: okButton, attribute: .Trailing, multiplier: 1, constant: 10)
let constraint17 = NSLayoutConstraint(item: okButton, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: okButtonWidth)
let constraint18 = NSLayoutConstraint(item: okButton, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: okButtonHeight)
let constraint19 = NSLayoutConstraint(item: okButton, attribute: .Top, relatedBy: .Equal, toItem: frameView, attribute: .Bottom, multiplier: 1, constant: 10)
// cancel button
let constraint20 = NSLayoutConstraint(item: view, attribute: .CenterX, relatedBy: .Equal, toItem: cancelButton, attribute: .Leading, multiplier: 1, constant: -10)
view.addConstraint(constraint0)
view.addConstraint(constraint1)
view.addConstraint(constraint12)
view.addConstraint(constraint13)
view.addConstraint(constraint14)
view.addConstraint(constraint15)
view.addConstraint(constraint16)
view.addConstraint(constraint17)
view.addConstraint(constraint18)
view.addConstraint(constraint19)
view.addConstraint(constraint20)
frameView.addConstraint(constraint2)
frameView.addConstraint(constraint3)
frameView.addConstraint(constraint4)
frameView.addConstraint(constraint5)
frameView.addConstraint(constraint6)
frameView.addConstraint(constraint7)
frameView.addConstraint(constraint8)
frameView.addConstraint(constraint9)
frameView.addConstraint(constraint10)
frameView.addConstraint(constraint11)
selectionCurrencyConstraintList = [constraint0, constraint1, constraint2, constraint3, constraint4, constraint5, constraint6, constraint7, constraint8, constraint9, constraint10, constraint11, constraint12, constraint13, constraint14, constraint15, constraint16, constraint17, constraint18, constraint19, constraint20]
frameView.hidden = true
okButton.hidden = true
cancelButton.hidden = true
此时,UIView 和两个按钮隐藏在屏幕顶部的正上方。
当我按下按钮使其出现时,我执行此代码:
frameView.hidden = hide
okButton.hidden = hide
cancelButton.hidden = hide
if var constraints = selectionCurrencyConstraintList {
let topFrameConstraint = constraints[0]
view.removeConstraint(topFrameConstraint)
constraints.removeAtIndex(0)
let newTopConstraint: NSLayoutConstraint!
if hide {
newTopConstraint = NSLayoutConstraint(item: okButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
} else {
newTopConstraint = NSLayoutConstraint(item: frameView, attribute: .Top, relatedBy: .Equal, toItem: topView, attribute: .Bottom, multiplier: 1, constant: margin)
}
constraints.insert(newTopConstraint, atIndex: 0)
view.addConstraint(newTopConstraint)
}
UIView.animateWithDuration(0.5) {
self.view.layoutIfNeeded()
}
当我用这个 NSLayoutConstraint(item: frameView, attribute: .Top, relatedBy: .Equal, toItem: topView, attribute: .Bottom, multiplier: 1, constant: margin)
替换这个约束 NSLayoutConstraint(item: okButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
时,它工作正常。
我在逆向的时候遇到了一些无法满足的约束:
2015-05-15 20:17:25.374 CurrencyEx[624:42779] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x17408de30 V:[UIView:0x174186660(50)]>",
"<NSLayoutConstraint:0x174090fe0 V:[_UILayoutGuide:0x1741a8a40]-(0)-[UIView:0x174186660]>",
"<_UILayoutSupportConstraint:0x1740a3e40 V:[_UILayoutGuide:0x1741a8a40(20)]>",
"<_UILayoutSupportConstraint:0x1740a3d80 V:|-(0)-[_UILayoutGuide:0x1741a8a40] (Names: '|':UIView:0x174186590 )>",
"<NSLayoutConstraint:0x170089150 V:[UIButton:0x146e49020(53)]>",
"<NSLayoutConstraint:0x1700891a0 V:[UIView:0x1741868d0]-(10)-[UIButton:0x146e49020]>",
"<NSLayoutConstraint:0x170088d90 V:[UIPickerView:0x146e09ef0(200)]>",
"<NSLayoutConstraint:0x170088e30 V:|-(-8)-[UIPickerView:0x146e09ef0] (Names: '|':UIView:0x1741868d0 )>",
"<NSLayoutConstraint:0x170088e80 UIPickerView:0x146e09ef0.bottom == UIView:0x1741868d0.bottom + 8>",
"<NSLayoutConstraint:0x17008ef60 V:[UIView:0x174186660]-(8)-[UIView:0x1741868d0]>",
"<NSLayoutConstraint:0x174096620 UIButton:0x146e49020.bottom == UIView:0x174186590.top>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x170088e80 UIPickerView:0x146e09ef0.bottom == UIView:0x1741868d0.bottom + 8>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-05-15 20:17:25.377 CurrencyEx[624:42779] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x17408de30 V:[UIView:0x174186660(50)]>",
"<NSLayoutConstraint:0x174090fe0 V:[_UILayoutGuide:0x1741a8a40]-(0)-[UIView:0x174186660]>",
"<_UILayoutSupportConstraint:0x1740a3e40 V:[_UILayoutGuide:0x1741a8a40(20)]>",
"<_UILayoutSupportConstraint:0x1740a3d80 V:|-(0)-[_UILayoutGuide:0x1741a8a40] (Names: '|':UIView:0x174186590 )>",
"<NSLayoutConstraint:0x170089150 V:[UIButton:0x146e49020(53)]>",
"<NSLayoutConstraint:0x1700891a0 V:[UIView:0x1741868d0]-(10)-[UIButton:0x146e49020]>",
"<NSLayoutConstraint:0x17008ef60 V:[UIView:0x174186660]-(8)-[UIView:0x1741868d0]>",
"<NSLayoutConstraint:0x174096620 UIButton:0x146e49020.bottom == UIView:0x174186590.top>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x17408de30 V:[UIView:0x174186660(50)]>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-05-15 20:17:25.378 CurrencyEx[624:42779] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x174090fe0 V:[_UILayoutGuide:0x1741a8a40]-(0)-[UIView:0x174186660]>",
"<_UILayoutSupportConstraint:0x1740a3e40 V:[_UILayoutGuide:0x1741a8a40(20)]>",
"<_UILayoutSupportConstraint:0x1740a3d80 V:|-(0)-[_UILayoutGuide:0x1741a8a40] (Names: '|':UIView:0x174186590 )>",
"<NSLayoutConstraint:0x170089150 V:[UIButton:0x146e49020(53)]>",
"<NSLayoutConstraint:0x1700891a0 V:[UIView:0x1741868d0]-(10)-[UIButton:0x146e49020]>",
"<NSLayoutConstraint:0x17008ef60 V:[UIView:0x174186660]-(8)-[UIView:0x1741868d0]>",
"<NSLayoutConstraint:0x174096620 UIButton:0x146e49020.bottom == UIView:0x174186590.top>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x1700891a0 V:[UIView:0x1741868d0]-(10)-[UIButton:0x146e49020]>
我不明白为什么。它首先适用于这些约束。当我修改其中一些时,它可以工作,而当我把它们放回去时,它就不再工作了...
有什么想法吗?
我们称您的约束为:
ConstraintHide
: okButton
底部与 superview 顶部对齐。
ConstraintShow
: frameView
比 topView
低 8 分。
如果您逐一检查日志中的冲突约束,您会注意到约束 ConstraintHide
和 ConstraintShow
同时存在。
这是您的 removal/addition 约束造成的。
- 初始状态
只有 ConstraintHide
在视图中
- 显示视图后的状态
ConstraintHide
正确删除,ConstraintShow
添加
- 隐藏视图后的状态
ConstraintShow
未删除,ConstraintHide
添加
- 碰撞
现在的问题是为什么第3步没有解除约束?这是因为步骤 2 中的错误。您的 selectionCurrencyConstraintList
未正确更新,因此在步骤 3 中您试图删除原始 ConstraintHide
约束而不是步骤 2 添加的约束 ConstraintShow
.
这是因为 if var constraints = selectionCurrencyConstraintList
复制了数组。所以最后要保存修改。
解决方案
添加
selectionCurrencyConstraintList = constraints
到块的末尾。
话虽如此,您可以通过在 Interface Builder 中添加所有约束来大大简化代码,连接 ConstraintShow
和 ConstraintHide
作为出口而不是 removing/addding 它们,只是将它们的优先级从 0
更改为 1000
。
这是我按下按钮之前的 UIViewController(我没有把它放在那里,因为它不相关):
当我按下按钮时,包含两个 UIPickerView 的 UIView 从顶部出现。在这个 UIView 的正下方是 2 个 UIButton。一切都适用于自动布局:
这是我创建约束时的代码:
let okButtonHeight: CGFloat = 53
let okButtonWidth: CGFloat = 53
let leftPickerViewWidth: CGFloat = 80
let leftPickerViewHeight: CGFloat = 200
let margin: CGFloat = 8
// frame
let constraint0 = NSLayoutConstraint(item: okButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
let constraint1 = NSLayoutConstraint(item: frameView, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0)
// left & right pickerViews
let constraint2 = NSLayoutConstraint(item: leftPickerView, attribute: .Width, relatedBy: .Equal, toItem: rightPickerView, attribute: .Width, multiplier: 1, constant: 0)
let constraint3 = NSLayoutConstraint(item: leftPickerView, attribute: .Height, relatedBy: .Equal, toItem: rightPickerView, attribute: .Height, multiplier: 1, constant: 0)
let constraint4 = NSLayoutConstraint(item: leftPickerView, attribute: .Trailing, relatedBy: .Equal, toItem: rightPickerView, attribute: .Leading, multiplier: 1, constant: -margin)
let constraint5 = NSLayoutConstraint(item: leftPickerView, attribute: .Top, relatedBy: .Equal, toItem: rightPickerView, attribute: .Top, multiplier: 1, constant: 0)
// left pickerView
let constraint6 = NSLayoutConstraint(item: leftPickerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: leftPickerViewHeight)
let constraint7 = NSLayoutConstraint(item: leftPickerView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: leftPickerViewWidth)
let constraint8 = NSLayoutConstraint(item: leftPickerView, attribute: .Top, relatedBy: .Equal, toItem: frameView, attribute: .Top, multiplier: 1, constant: -margin)
let constraint9 = NSLayoutConstraint(item: leftPickerView, attribute: .Bottom, relatedBy: .Equal, toItem: frameView, attribute: .Bottom, multiplier: 1, constant: margin)
let constraint10 = NSLayoutConstraint(item: leftPickerView, attribute: .Leading, relatedBy: .Equal, toItem: frameView, attribute: .Leading, multiplier: 1, constant: margin)
// right pickerView
let constraint11 = NSLayoutConstraint(item: rightPickerView, attribute: .Trailing, relatedBy: .Equal, toItem: frameView, attribute: .Trailing, multiplier: 1, constant: -margin)
// ok & cancel buttons
let constraint12 = NSLayoutConstraint(item: okButton, attribute: .Top, relatedBy: .Equal, toItem: cancelButton, attribute: .Top, multiplier: 1, constant: 0)
let constraint13 = NSLayoutConstraint(item: okButton, attribute: .Bottom, relatedBy: .Equal, toItem: cancelButton, attribute: .Bottom, multiplier: 1, constant: 0)
let constraint14 = NSLayoutConstraint(item: okButton, attribute: .Width, relatedBy: .Equal, toItem: cancelButton, attribute: .Width, multiplier: 1, constant: 0)
let constraint15 = NSLayoutConstraint(item: okButton, attribute: .Height, relatedBy: .Equal, toItem: cancelButton, attribute: .Height, multiplier: 1, constant: 0)
// ok button
let constraint16 = NSLayoutConstraint(item: view, attribute: .CenterX, relatedBy: .Equal, toItem: okButton, attribute: .Trailing, multiplier: 1, constant: 10)
let constraint17 = NSLayoutConstraint(item: okButton, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: okButtonWidth)
let constraint18 = NSLayoutConstraint(item: okButton, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: okButtonHeight)
let constraint19 = NSLayoutConstraint(item: okButton, attribute: .Top, relatedBy: .Equal, toItem: frameView, attribute: .Bottom, multiplier: 1, constant: 10)
// cancel button
let constraint20 = NSLayoutConstraint(item: view, attribute: .CenterX, relatedBy: .Equal, toItem: cancelButton, attribute: .Leading, multiplier: 1, constant: -10)
view.addConstraint(constraint0)
view.addConstraint(constraint1)
view.addConstraint(constraint12)
view.addConstraint(constraint13)
view.addConstraint(constraint14)
view.addConstraint(constraint15)
view.addConstraint(constraint16)
view.addConstraint(constraint17)
view.addConstraint(constraint18)
view.addConstraint(constraint19)
view.addConstraint(constraint20)
frameView.addConstraint(constraint2)
frameView.addConstraint(constraint3)
frameView.addConstraint(constraint4)
frameView.addConstraint(constraint5)
frameView.addConstraint(constraint6)
frameView.addConstraint(constraint7)
frameView.addConstraint(constraint8)
frameView.addConstraint(constraint9)
frameView.addConstraint(constraint10)
frameView.addConstraint(constraint11)
selectionCurrencyConstraintList = [constraint0, constraint1, constraint2, constraint3, constraint4, constraint5, constraint6, constraint7, constraint8, constraint9, constraint10, constraint11, constraint12, constraint13, constraint14, constraint15, constraint16, constraint17, constraint18, constraint19, constraint20]
frameView.hidden = true
okButton.hidden = true
cancelButton.hidden = true
此时,UIView 和两个按钮隐藏在屏幕顶部的正上方。
当我按下按钮使其出现时,我执行此代码:
frameView.hidden = hide
okButton.hidden = hide
cancelButton.hidden = hide
if var constraints = selectionCurrencyConstraintList {
let topFrameConstraint = constraints[0]
view.removeConstraint(topFrameConstraint)
constraints.removeAtIndex(0)
let newTopConstraint: NSLayoutConstraint!
if hide {
newTopConstraint = NSLayoutConstraint(item: okButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
} else {
newTopConstraint = NSLayoutConstraint(item: frameView, attribute: .Top, relatedBy: .Equal, toItem: topView, attribute: .Bottom, multiplier: 1, constant: margin)
}
constraints.insert(newTopConstraint, atIndex: 0)
view.addConstraint(newTopConstraint)
}
UIView.animateWithDuration(0.5) {
self.view.layoutIfNeeded()
}
当我用这个 NSLayoutConstraint(item: frameView, attribute: .Top, relatedBy: .Equal, toItem: topView, attribute: .Bottom, multiplier: 1, constant: margin)
替换这个约束 NSLayoutConstraint(item: okButton, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
时,它工作正常。
我在逆向的时候遇到了一些无法满足的约束:
2015-05-15 20:17:25.374 CurrencyEx[624:42779] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x17408de30 V:[UIView:0x174186660(50)]>",
"<NSLayoutConstraint:0x174090fe0 V:[_UILayoutGuide:0x1741a8a40]-(0)-[UIView:0x174186660]>",
"<_UILayoutSupportConstraint:0x1740a3e40 V:[_UILayoutGuide:0x1741a8a40(20)]>",
"<_UILayoutSupportConstraint:0x1740a3d80 V:|-(0)-[_UILayoutGuide:0x1741a8a40] (Names: '|':UIView:0x174186590 )>",
"<NSLayoutConstraint:0x170089150 V:[UIButton:0x146e49020(53)]>",
"<NSLayoutConstraint:0x1700891a0 V:[UIView:0x1741868d0]-(10)-[UIButton:0x146e49020]>",
"<NSLayoutConstraint:0x170088d90 V:[UIPickerView:0x146e09ef0(200)]>",
"<NSLayoutConstraint:0x170088e30 V:|-(-8)-[UIPickerView:0x146e09ef0] (Names: '|':UIView:0x1741868d0 )>",
"<NSLayoutConstraint:0x170088e80 UIPickerView:0x146e09ef0.bottom == UIView:0x1741868d0.bottom + 8>",
"<NSLayoutConstraint:0x17008ef60 V:[UIView:0x174186660]-(8)-[UIView:0x1741868d0]>",
"<NSLayoutConstraint:0x174096620 UIButton:0x146e49020.bottom == UIView:0x174186590.top>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x170088e80 UIPickerView:0x146e09ef0.bottom == UIView:0x1741868d0.bottom + 8>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-05-15 20:17:25.377 CurrencyEx[624:42779] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x17408de30 V:[UIView:0x174186660(50)]>",
"<NSLayoutConstraint:0x174090fe0 V:[_UILayoutGuide:0x1741a8a40]-(0)-[UIView:0x174186660]>",
"<_UILayoutSupportConstraint:0x1740a3e40 V:[_UILayoutGuide:0x1741a8a40(20)]>",
"<_UILayoutSupportConstraint:0x1740a3d80 V:|-(0)-[_UILayoutGuide:0x1741a8a40] (Names: '|':UIView:0x174186590 )>",
"<NSLayoutConstraint:0x170089150 V:[UIButton:0x146e49020(53)]>",
"<NSLayoutConstraint:0x1700891a0 V:[UIView:0x1741868d0]-(10)-[UIButton:0x146e49020]>",
"<NSLayoutConstraint:0x17008ef60 V:[UIView:0x174186660]-(8)-[UIView:0x1741868d0]>",
"<NSLayoutConstraint:0x174096620 UIButton:0x146e49020.bottom == UIView:0x174186590.top>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x17408de30 V:[UIView:0x174186660(50)]>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-05-15 20:17:25.378 CurrencyEx[624:42779] 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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x174090fe0 V:[_UILayoutGuide:0x1741a8a40]-(0)-[UIView:0x174186660]>",
"<_UILayoutSupportConstraint:0x1740a3e40 V:[_UILayoutGuide:0x1741a8a40(20)]>",
"<_UILayoutSupportConstraint:0x1740a3d80 V:|-(0)-[_UILayoutGuide:0x1741a8a40] (Names: '|':UIView:0x174186590 )>",
"<NSLayoutConstraint:0x170089150 V:[UIButton:0x146e49020(53)]>",
"<NSLayoutConstraint:0x1700891a0 V:[UIView:0x1741868d0]-(10)-[UIButton:0x146e49020]>",
"<NSLayoutConstraint:0x17008ef60 V:[UIView:0x174186660]-(8)-[UIView:0x1741868d0]>",
"<NSLayoutConstraint:0x174096620 UIButton:0x146e49020.bottom == UIView:0x174186590.top>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x1700891a0 V:[UIView:0x1741868d0]-(10)-[UIButton:0x146e49020]>
我不明白为什么。它首先适用于这些约束。当我修改其中一些时,它可以工作,而当我把它们放回去时,它就不再工作了...
有什么想法吗?
我们称您的约束为:
ConstraintHide
: okButton
底部与 superview 顶部对齐。
ConstraintShow
: frameView
比 topView
低 8 分。
如果您逐一检查日志中的冲突约束,您会注意到约束 ConstraintHide
和 ConstraintShow
同时存在。
这是您的 removal/addition 约束造成的。
- 初始状态
只有 ConstraintHide
在视图中
- 显示视图后的状态
ConstraintHide
正确删除,ConstraintShow
添加
- 隐藏视图后的状态
ConstraintShow
未删除,ConstraintHide
添加
- 碰撞
现在的问题是为什么第3步没有解除约束?这是因为步骤 2 中的错误。您的 selectionCurrencyConstraintList
未正确更新,因此在步骤 3 中您试图删除原始 ConstraintHide
约束而不是步骤 2 添加的约束 ConstraintShow
.
这是因为 if var constraints = selectionCurrencyConstraintList
复制了数组。所以最后要保存修改。
解决方案
添加
selectionCurrencyConstraintList = constraints
到块的末尾。
话虽如此,您可以通过在 Interface Builder 中添加所有约束来大大简化代码,连接 ConstraintShow
和 ConstraintHide
作为出口而不是 removing/addding 它们,只是将它们的优先级从 0
更改为 1000
。