以编程方式在Swift中添加约束

13

我正在尝试为Facebook SDK登录按钮添加约束。

我将按钮放置在滚动视图中,并尝试为滚动视图中的标签添加一个顶部约束。我已经成功添加了高度约束,没有运行时错误,但实际的约束似乎并未应用于按钮上。

@IBOutlet weak var orLbl: UILabel!
@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()
    var loginFBButton = FBSDKLoginButton()
    loginFBButton.readPermissions = ["public_profile", "email"]

    let heightConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Height,
        relatedBy: NSLayoutRelation.Equal,
        toItem: nil,
        attribute: NSLayoutAttribute.NotAnAttribute,
        multiplier: 1,
        constant: 41)
    let topConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.TopMargin,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.orLbl,
        attribute: NSLayoutAttribute.BottomMargin,
        multiplier: 1,
        constant: 31)
    let leadingConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.registerButton,
        attribute: NSLayoutAttribute.Left,
        multiplier: 1,
        constant: 0)
    let trailingConstraint = NSLayoutConstraint(
        item: loginFBButton,
        attribute: NSLayoutAttribute.Leading,
        relatedBy: NSLayoutRelation.Equal,
        toItem: self.registerButton,
        attribute: NSLayoutAttribute.Right,
        multiplier: 1,
        constant: 0)

    self.scrollView.addSubview(loginFBButton)
    //loginFBButton.center = self.scrollView.center

    loginFBButton.addConstraints([heightConstraint, topConstraint])

}

当我添加顶部约束时,出现了运行时错误:

将约束添加到视图中时,其项目必须是该视图的后代(或视图本身)。如果需要在视图层次结构组装之前解析约束,则会崩溃。

终止应用程序,原因是未捕获的异常 'NSGenericException',原因:无法在视图上安装约束。约束引用了视图子树之外的内容吗?那是非法的。

标签和Facebook按钮都在我的滚动视图中?我甚至已经打印出orLbl.superview和loginFBButton.superview,并且对于这两个对象都得到可选的uiscrollview。


你尝试过找出是哪个约束条件导致了异常吗? - freytag
@freytag 是的,正如问题中提到的那样,当我添加顶部约束时,崩溃就会发生。另一个用户建议将约束添加到滚动视图而不是loginFBButton。我这样做了,没有运行时错误,但我的Facebook按钮现在位于屏幕左上角,或标签完全超出屏幕范围。 - user2363025
1个回答

29

现在有一种新的(iOS8、OS 10.10)更简单的方法来激活约束,不需要弄清哪些视图要添加约束。约束已经知道它们属于哪些视图,所以首先确保您的视图已添加为子视图,然后调用NSLayoutConstraint类方法activateConstraints来激活它们:

 NSLayoutConstraint.activateConstraints([heightConstraint, topConstraint])

当您以编程方式创建UI元素时,您需要告诉iOS不要将其框架转换为约束条件。为此,请在创建loginFBButton之后执行以下操作:

对于Swift 1.2:

loginFBButton.setTranslatesAutoresizingMaskIntoConstraints(false)

对于 Swift 2.0 和 3.0:

loginFBButton.translatesAutoresizingMaskIntoConstraints = false

最后,您需要更多的约束条件。我建议为您的loginFBButton设置宽度约束,并添加一个水平定位约束来定位该按钮。


我已经更新了代码以包含我正在使用的所有约束条件。那么此时我还需要添加约束条件,然后设置translateAutoresizingMaskIntoConstraints布尔值,或者流程是什么? - user2363025
创建你的按钮,将 translatesAutoresizingMaskIntoConstraints 设置为 false,将按钮添加到 scrollView 中,创建约束并激活它们。 - vacawama
谢谢,我使用loginFBButton.setTranslatesAutoresizingMaskIntoConstraints(false)让它工作了。我还必须确保将约束添加到滚动视图而不是loginFBButton上。但我没有必要使用激活约束。 - user2363025
是的,激活约束并不是必需的,只是比找出哪些视图添加约束要容易得多。 - vacawama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接