以编程方式创建绑定到视图控制器边距的约束



我正在尝试制作一个视图,它将作为一种"面板",连接到视图控制器的右侧。

也就是说,它绑定到父视图控制器的尾部、顶部和底部边缘,静态宽度为300

然而,我似乎无法做到正确,我要么打破了限制,要么做了xcode告诉我的违法行为。

我做错了什么?

这是控制器中的代码

    let myView = UIView()
    view.backgroundColor = UIColor.redColor()
    self.view.addSubview(view)
    let topConstraint = NSLayoutConstraint(item: myView,
                                           attribute: .Top,
                                           relatedBy: .Equal,
                                           toItem: self.topLayoutGuide,
                                           attribute: .Bottom,
                                           multiplier: 1,
                                           constant: 0)
    let trailingConstraint = NSLayoutConstraint(item: self.view,
                                                attribute: .TrailingMargin,
                                                relatedBy: .Equal,
                                                toItem: myView,
                                                attribute: .Trailing,
                                                multiplier: 1,
                                                constant: 0)
    let bottomConstraint = NSLayoutConstraint(item: self.bottomLayoutGuide,
                                              attribute: .Top,
                                              relatedBy: .Equal,
                                              toItem: myView,
                                              attribute: .Bottom,
                                              multiplier: 1,
                                              constant: 0)
    let widthConstraint = NSLayoutConstraint(item: myView,
                                             attribute: .Width,
                                             relatedBy: .Equal,
                                             toItem: nil,
                                             attribute: .NotAnAttribute,
                                             multiplier: 1,
                                             constant: 300)
    self.view.addConstraints([trailingConstraint])
    view.addConstraints([topConstraint, bottomConstraint, widthConstraint])

实际上,代码中的问题是您没有将myviewtranslatesAutoresizingMaskIntoConstraints设置为false,无论何时您想要使用自动布局约束,都必须将视图的translatesAutoresizingMaskIntoConstraints设置为false。另一个问题是你没有在self.view上添加myview。我已经更新了你的代码,它可以根据你的限制正常工作。

将以下代码放入您的ViewController中。

let myView = UIView()
myView.backgroundColor = UIColor.redColor()
self.view.addSubview(myView)
myView.translatesAutoresizingMaskIntoConstraints = false
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Bottom, relatedBy: .Equal, toItem: self.bottomLayoutGuide, attribute:.Top, multiplier: 1, constant: 20))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 300))
view.addConstraint(NSLayoutConstraint(item: myView, attribute: .TrailingMargin, relatedBy: .Equal, toItem: view, attribute: .TrailingMargin, multiplier: 1, constant: 0))

在上面的示例代码中,似乎在一些地方混淆了viewmyView。在任何情况下,应将widthConstraint添加到myView,并将topConstrainttrailingConstraintbottomConstraint添加到self.view。原因是必须将约束添加到最近的超视图祖先,该父视图列出了约束中涉及的两个视图。如果要将子视图属性约束到其父视图上的某个属性,则必须将约束添加到父视图中,因为它同时布置自身和子视图。如果在两个同级视图之间有约束,则该约束将添加到其父视图中,因为它是布置两个相关视图的最接近的祖先。

如果您能够以iOS 9.0及更高版本为目标,那么使用新的NSLayoutAnchor和NSLayoutDimension API来创建这些类型的约束会更干净、更容易。它还提供了严格的类型检查,编译器可以验证正确性。有了这些新的API,您的示例代码将简单地变成:

let myView = UIView()
myView.backgroundColor = UIColor.redColor()
self.view.addSubview(myView)
let margins = self.view.layoutMarginsGuide
myView.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor).active = true
myView.topAnchor.constraintEqualToAnchor(margins.topAnchor).active = true
myView.bottomAnchor.constraintEqualToAnchor(margins.bottomAnchor).active = true
myView.widthAnchor.constraintEqualToConstant(300.0).active = true

无需在右侧视图中明确添加约束等。您可以在此处阅读更多关于创建约束的方法:

https://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutAnchor_ClassReference/

这里:

https://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutDimension_ClassReference/

您的代码中似乎有一些歧义,您将创建一个UIView作为myView,但将视图添加到self.view,甚至还将约束添加到视图本身。因此,请更正您的代码并将视图替换为myView。其次,将TranslayesAutoresizingMaskIntoConstraints设置为false。然后将所有约束添加到self.view。这应该可以解决您的问题。

 myView.setTranslatesAutoresizingMaskIntoConstraints(false)
 self.view.addConstraints([trailingConstraint, bottomConstraint, widthConstraint])

VFL也是一种更好、更干净的方法。它实际上提供了如何设置约束的可视化。

最新更新