添加后更改约束会导致约束错误(swift)

时间:2015-03-04 23:07:10

标签: ios swift constraints

我正在努力将错误消息添加到我的登录屏幕。

虽然代码运行良好,并且做了我想要它做的事情。它会导致执行时出现约束错误。

以下是受影响的约束:

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解决方案,约束一个带常数的变量,然后改变常量。 - 我试着把它翻译成快速的。运行时没有错误,但我的errorView没有显示(高度不会改变)

这是我试过的:

  1. 我在ViewController类中声明了变量(在viewDidLoad之前)

    var errorViewHeight = NSLayoutConstraint()

  2. 在我的函数开头,我指定它。

    errorViewHeight = NSLayoutConstraint(item:errorView,attribute:NSLayoutAttribute.Height,relatedBy:NSLayoutRelation.Equal,toItem:nil,attribute:NSLayoutAttribute.NotAnAttribute,multiplier:1.0,constant:0)

  3. 最后,在if语句返回true后,我尝试对其进行动画处理。

    UIView.animateWithDuration(0.2,动画:{() - > Void in             self.errorViewHeight.constant = 50             self.view.layoutIfNeeded()         })

  4. 编辑:

    以下是错误消息:

    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.
    

3 个答案:

答案 0 :(得分:0)

我想出了如何使用常量更改约束。

在viewController类中我定义了约束:

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

希望能帮助某人寻找同样的问题。

答案 1 :(得分:0)

您可以通过添加以下扩展名来更改任何约束,如果您要部署到多个设备,这是非常好的:

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()
    }
}

答案 2 :(得分:0)

我要补充的是,有些人习惯在 viewDidLayout 方法中设置约束,因此,当您更改或编辑任何约束时,都会出现此错误,即 viewDidLayout 不能与 viewDidLoad 或其他功能一起使用。因此,我的建议是,如果您正在执行类似操作,请使用 viewDidAppear 而不是 viewDidLayout ,最好是使用 viewDidLoad