在Swift中设置UIButton上的Autolayout约束

时间:2015-06-17 16:20:11

标签: ios iphone swift constraints

我仍然试图在XCode 6.3中了解Swift Autolayouts。我已经设置了一个View Controller,我在Interface Builder中粘贴了几个标签。我已经以编程方式添加了UITextView和UIImageView,并且我尝试在屏幕底部添加UIButton并以编程方式设置其约束。但是,当视图尝试加载时,我不断收到错误。

在课程定义下:

let infoButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton
var descView: UITextView!
var picView: UIImageView!

override func viewDidLoad() {
  super.viewDidLoad()
  infoButton.setTranslatesAutoresizingMaskIntoConstraints(false)
  infoButton.setTitle("Information",forState:UIControlState.Normal)
  self.view.addSubview(infoButton)

self.descView = UITextView(frame:CGRectMake(0,0,300,290))
self.descView.selectable = false
self.userInteractionEnabled = false
self.descView.text = "testing block of text"

self.container.frame = CGRect(x:20,y:160,width:300,height:290)
self.picView = UIImageView(image:"house.png")
self.view.addSubview(container)
self.container.addSubview(picView)

//setup button constraints
let viewsDictionary = ["infoButton":infoButton]
let button_constraint_H:Array = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[infoButton]-|", options:NSLayoutFormatOptions(0),metrics:nil,views:viewsDictionary)
let button_constraint_V:Array = NSLayoutConstraint.constraintsWithVisualFormat("V:[infoButton]-0-|",options:NSLayoutFormatOptions(0),metrics:nil, views:viewsDictionary)
infoButton.addConstraints(button_constraint_H)
infoButton.addConstraints(button_constraint_V)

}

该应用在viewDidLoad()方法中崩溃。

2015-06-17 16:59:14.902 LayoutTest[20323:5937743] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7fc5b9de4140 UIButton:0x7fc5b9ec3e40'Information'.leading == UIView:0x7fc5b9eaf860.leadingMargin>
When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug.
2015-06-17 16:59:14.904 LayoutTest[20323:5937743] View hierarchy unprepared for constraint.
Constraint: <NSLayoutConstraint:0x7fc5b9de4140 UIButton:0x7fc5b9ec3e40'Information'.leading == UIView:0x7fc5b9eaf860.leadingMargin>
Container hierarchy: 
<UIButton: 0x7fc5b9ec3e40; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x7fc5b9ee2a80>>
View not found in container hierarchy: <UIView: 0x7fc5b9eaf860; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7fc5b9ed9c70>>
That view's superview: NO SUPERVIEW
2015-06-17 16:59:14.925 LayoutTest[20323:5937743] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view.  Does the constraint reference something from outside the subtree of the view?  That's illegal. constraint:<NSLayoutConstraint:0x7fc5b9de4140 UIButton:0x7fc5b9ec3e40'Information'.leading == UIView:0x7fc5b9eaf860.leadingMargin> view:<UIButton: 0x7fc5b9ec3e40; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x7fc5b9ee2a80>>'

我到底做错了什么? 我已经使用Interface Builder为其他项(标签)定义了一些约束,但需要能够定义按钮等,并通过代码为同一视图设置约束。

这是我与Swift的第一周,所以要温柔! 金

3 个答案:

答案 0 :(得分:5)

试试这段代码

        self.view.addConstraint(NSLayoutConstraint(item: infoButton, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Leading, multiplier: 1.0, constant: 0.0))
        self.view.addConstraint(NSLayoutConstraint(item: infoButton, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.Trailing, multiplier: 1.0, constant: 0.0))
        self.view.addConstraint(NSLayoutConstraint(item: infoButton, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: 0.0))

答案 1 :(得分:2)

您看到的特定崩溃是因为您要将约束添加到按钮,而不是它的超级视图。约束与self.viewinfoButton相关,因此应添加到self.view。如果约束仅与按钮相关,即它正在定义按钮高度,则通过与另一个视图无关的显式值,则可以将其添加到按钮。您也不能轻易地在同一视图中混合设置框架和约束,您可能最终会得到一个您不期望的视图布局。 descViewcontainerpicView都需要通过约束来定义,而不是手动设置框架。

更改行

infoButton.addConstraints(button_constraint_H)
infoButton.addConstraints(button_constraint_V)

self.view.addConstraints(button_constraint_H)
self.view.addConstraints(button_constraint_V)

这里的自动布局代码存在一些问题,其中一些非常基础。 Autolayout会花一点时间来解决问题,有时候它很古怪。你会真正受益于对它的彻底阅读。潜水并试图在你去的时候解决它将导致你进入一些非常令人沮丧的情况。我建议从Apple阅读本指南:

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/index.html#//apple_ref/doc/uid/TP40010853-CH7-SW1

阅读本书的前4-5章:

https://itunes.apple.com/gb/book/ios-auto-layout-demystified/id727646366?mt=11

并在此处举例说明:

http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1

答案 2 :(得分:0)

所以我认为你只是为你的按钮设置约束,但是autolayout需要对视图层次结构中的所有元素都有约束。

您将按钮和容器添加到超级视图中,而不说它们之间的关系我认为您只需要更多约束。

我建议使用storyboard进行尝试,因为我发现视图和约束是如何相关的更清楚。

无论如何,祝你好运。