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

问题描述:

我试图制作一个视图,它将充当一种“面板”,连接到视图控制器的右侧。以编程方式创建绑定到视图控制器边界的约束

也就是说,它必然尾随,顶部,父视图控制器的底部边缘,与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]) 
+1

为什么你不使用Visual Format Language? ''H:[panel(300)] |'和'“V:| [toplayout] [panel] [botlayout] |”'应该足够了 – Eendje

其实在你的代码的问题是,你D编号没有设置translatesAutoresizingMaskIntoConstraintsmyviewfalse,只要你想使用自动布局约束,那么你必须将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)) 
+1

如果你想以更容易的方式通过编程方式添加约束, ://github.com/keshavvishwkarma/KVConstraintExtensionsMaster。 –

+0

如果你真的喜欢我的答案,那么你也会投票。 –

的代码似乎是在你的代码中的一些不确定性,要创建一个UIView作为MyView的,但加入以self.view,甚至也制约查看本身。所以纠正你的代码并用myView替换视图。 其次setTranslayesAutoresizingMaskIntoConstraints为false。 然后将所有约束添加到self.view。这应该可以解决你的问题。

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

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

在上面的示例代码中,好像在几个地方混合了viewmyView。无论如何,widthConstraint应该被添加到myViewtopConstrainttrailingConstraintbottomConstraint应该被添加到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/