我正在尝试制作一个视图,它将作为一种"面板",连接到视图控制器的右侧。
也就是说,它绑定到父视图控制器的尾部、顶部和底部边缘,静态宽度为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])
实际上,代码中的问题是您没有将myview
的translatesAutoresizingMaskIntoConstraints
设置为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))
在上面的示例代码中,似乎在一些地方混淆了view
和myView
。在任何情况下,应将widthConstraint
添加到myView
,并将topConstraint
、trailingConstraint
和bottomConstraint
添加到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也是一种更好、更干净的方法。它实际上提供了如何设置约束的可视化。