添加后更改约束会导致约束错误 (swift)
Changing constraint after adding it causes constraint error (swift)
我正在努力将错误消息添加到我的登录屏幕。
虽然代码 运行 没问题,但可以按我的要求执行。它会导致执行约束错误。
以下是受影响的约束:
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]-32-[emailInputField]-32-[passwordInputField]-32-[signInButton]-16-[resetPasswordButton]-[signUpButton]", options: nil, metrics: nil, views: viewsDictionary))
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]-32-[emailIconBox]-32-[passwordIconBox]", options: nil, metrics: nil, views: viewsDictionary))
这里是导致 errorView 出现的函数。
// sign in button function
func signIn(sender: UIButton) {
self.view.endEditing(true)
if emailInputField.text.isEmpty {
println("NO EMAIL")
errorLabel.attributedText = UILabel.ErrorMessage("Form fields cannot be empty!")
var viewsDictionary = [ "topBar":topBar,
"errorView":errorView,
"errorLabel":errorLabel,
"emailInputField":emailInputField,
"emailIconBox":emailIconBox,
"passwordInputField":passwordInputField,
"passwordIconBox":passwordIconBox,
"signInButton":signInButton,
"resetPasswordButton":resetPasswordButton,
"signUpButton":signUpButton]
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]-16-[errorView]-16-[emailInputField]-32-[passwordInputField]-32-[signInButton]-16-[resetPasswordButton]-[signUpButton]", options: nil, metrics: nil, views: viewsDictionary))
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]-16-[errorView]-16-[emailIconBox]-32-[passwordIconBox]", options: nil, metrics: nil, views: viewsDictionary))
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:[errorView(50)]", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary))
}
}
如何在不破坏约束的情况下更改约束?
我尝试了 self.view.updateConstraints() - 但没有任何作用。
我也尝试在添加约束之前删除约束,但仍然存在错误。
如有任何帮助,我们将不胜感激!
编辑:
我找到了一个 objective-c 解决方案,用一个常量约束一个变量,然后改变常量。 - 我尝试将其翻译成 swift。当我 运行 它时没有错误,但是我的 errorView 没有显示(高度没有改变)
这是我尝试过的:
我在ViewControllerclass(viewDidLoad之前)声明了变量
var errorViewHeight = NSLayoutConstraint()
在我函数的开头,我指定了它。
errorViewHeight = NSLayoutConstraint(item:errorView, attribute:NSLayoutAttribute.Height, relatedBy:NSLayoutRelation.Equal, toItem:nil, attribute:NSLayoutAttribute.NotAnAttribute, multiplier:1.0 , constant:0)
最后,在 if 语句 returns 为真之后,我尝试为其设置动画。
UIView.animateWithDuration(0.2, 动画: { () -> Void in
self.errorViewHeight.constant = 50
self.view.layoutIfNeeded()
})
编辑:
错误信息如下:
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:0x170089e20 V:[UIView:0x174191780(0)]>",
"<NSLayoutConstraint:0x170089fb0 V:[UIView:0x174191780(50)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x170089fb0 V:[UIView:0x174191780(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.
我想出了如何使用常量更改约束。
在viewControllerclass中我定义了约束:
var errorViewHeight:NSLayoutConstraint!
并且在 viewDidLoad 中,我指定并将其添加到我的 UIView
errorViewHeight = NSLayoutConstraint(item:errorView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier:1.0, constant:0)
errorView.addConstraint(errorViewHeight)
从那时起,我可以使用以下代码行正确更改高度
errorViewHeight.constant = 50
希望对寻找相同问题的人有所帮助。
您可以通过添加以下扩展来更改任何约束,如果您要部署到多个设备,那将是极好的:
extension UIView
{
func updateHieghtForView()
{
var constant = CGFloat()
// change the constant by switching device type by screen size
let allConstraints = self.constraints
for heightConstraint in allConstraints
{
if heightConstraint.firstAttribute == .Height
{
self.removeConstraint(heightConstraint)
}
}
let layOutConstaint = NSLayoutConstraint(item: self,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute:.Height,
multiplier: 1,
constant: constant)
self.addConstraint(layOutConstaint)
self.updateConstraints()
}
}
我的回答我想补充的是,有些人有在viewDidLayout方法中设置约束的习惯,所以当你改变或编辑任何约束时,它会给你这个错误因为 viewDidLayout 不像 viewDidLoad 或其他函数那样工作。所以我的建议是,如果你正在做这样的事情,请使用 viewDidAppear 而不是 viewDidLayout,最好使用 viewDidLoad.
我正在努力将错误消息添加到我的登录屏幕。
虽然代码 运行 没问题,但可以按我的要求执行。它会导致执行约束错误。
以下是受影响的约束:
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]-32-[emailInputField]-32-[passwordInputField]-32-[signInButton]-16-[resetPasswordButton]-[signUpButton]", options: nil, metrics: nil, views: viewsDictionary))
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]-32-[emailIconBox]-32-[passwordIconBox]", options: nil, metrics: nil, views: viewsDictionary))
这里是导致 errorView 出现的函数。
// sign in button function
func signIn(sender: UIButton) {
self.view.endEditing(true)
if emailInputField.text.isEmpty {
println("NO EMAIL")
errorLabel.attributedText = UILabel.ErrorMessage("Form fields cannot be empty!")
var viewsDictionary = [ "topBar":topBar,
"errorView":errorView,
"errorLabel":errorLabel,
"emailInputField":emailInputField,
"emailIconBox":emailIconBox,
"passwordInputField":passwordInputField,
"passwordIconBox":passwordIconBox,
"signInButton":signInButton,
"resetPasswordButton":resetPasswordButton,
"signUpButton":signUpButton]
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]-16-[errorView]-16-[emailInputField]-32-[passwordInputField]-32-[signInButton]-16-[resetPasswordButton]-[signUpButton]", options: nil, metrics: nil, views: viewsDictionary))
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[topBar]-16-[errorView]-16-[emailIconBox]-32-[passwordIconBox]", options: nil, metrics: nil, views: viewsDictionary))
self.view.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat(
"V:[errorView(50)]", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary))
}
}
如何在不破坏约束的情况下更改约束?
我尝试了 self.view.updateConstraints() - 但没有任何作用。 我也尝试在添加约束之前删除约束,但仍然存在错误。
如有任何帮助,我们将不胜感激!
编辑:
我找到了一个 objective-c 解决方案,用一个常量约束一个变量,然后改变常量。 - 我尝试将其翻译成 swift。当我 运行 它时没有错误,但是我的 errorView 没有显示(高度没有改变)
这是我尝试过的:
我在ViewControllerclass(viewDidLoad之前)声明了变量
var errorViewHeight = NSLayoutConstraint()
在我函数的开头,我指定了它。
errorViewHeight = NSLayoutConstraint(item:errorView, attribute:NSLayoutAttribute.Height, relatedBy:NSLayoutRelation.Equal, toItem:nil, attribute:NSLayoutAttribute.NotAnAttribute, multiplier:1.0 , constant:0)
最后,在 if 语句 returns 为真之后,我尝试为其设置动画。
UIView.animateWithDuration(0.2, 动画: { () -> Void in self.errorViewHeight.constant = 50 self.view.layoutIfNeeded() })
编辑:
错误信息如下:
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:0x170089e20 V:[UIView:0x174191780(0)]>",
"<NSLayoutConstraint:0x170089fb0 V:[UIView:0x174191780(50)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x170089fb0 V:[UIView:0x174191780(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.
我想出了如何使用常量更改约束。
在viewControllerclass中我定义了约束:
var errorViewHeight:NSLayoutConstraint!
并且在 viewDidLoad 中,我指定并将其添加到我的 UIView
errorViewHeight = NSLayoutConstraint(item:errorView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier:1.0, constant:0)
errorView.addConstraint(errorViewHeight)
从那时起,我可以使用以下代码行正确更改高度
errorViewHeight.constant = 50
希望对寻找相同问题的人有所帮助。
您可以通过添加以下扩展来更改任何约束,如果您要部署到多个设备,那将是极好的:
extension UIView
{
func updateHieghtForView()
{
var constant = CGFloat()
// change the constant by switching device type by screen size
let allConstraints = self.constraints
for heightConstraint in allConstraints
{
if heightConstraint.firstAttribute == .Height
{
self.removeConstraint(heightConstraint)
}
}
let layOutConstaint = NSLayoutConstraint(item: self,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute:.Height,
multiplier: 1,
constant: constant)
self.addConstraint(layOutConstaint)
self.updateConstraints()
}
}
我的回答我想补充的是,有些人有在viewDidLayout方法中设置约束的习惯,所以当你改变或编辑任何约束时,它会给你这个错误因为 viewDidLayout 不像 viewDidLoad 或其他函数那样工作。所以我的建议是,如果你正在做这样的事情,请使用 viewDidAppear 而不是 viewDidLayout,最好使用 viewDidLoad.