Mar*_*man 73 xcode ios autolayout nslayoutconstraint swift
我有一个UITableViewController,如果没有任何显示,它不会显示任何部分.我添加了一个标签,向用户表明此代码无法显示:
label = UILabel(frame: CGRectMake(20, 20, 250, 100))
label.text = "Nothing to show"
self.tableView.addSubview(label)
Run Code Online (Sandbox Code Playgroud)
但现在,我希望它在水平和垂直方向上居中.通常,我会在屏幕截图中选择突出显示的两个选项(加上高度和宽度的选项):
我尝试了以下代码来添加约束但应用程序崩溃时出现错误:
label = UILabel(frame: CGRectMake(20, 20, 250, 100))
label.text = "Nothing to show"
let xConstraint = NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: self.tableView, attribute: .CenterX, multiplier: 1, constant: 0)
let yConstraint = NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: self.tableView, attribute: .CenterY, multiplier: 1, constant: 0)
label.addConstraint(xConstraint)
label.addConstraint(yConstraint)
Run Code Online (Sandbox Code Playgroud)
错误:
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.
2014-12-23 08:17:36.755 [982:227877] *** Assertion failure in -[UILabel _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /SourceCache/UIKit/UIKit-3318.16.21/NSLayoutConstraint_UIKitAdditions.m:560
Run Code Online (Sandbox Code Playgroud)
标签应始终水平和垂直居中,因为应用程序支持设备的旋转.
我究竟做错了什么?如何成功添加这些约束?
谢谢!
vac*_*ama 138
Swift 3/Swift 4的更新:
从iOS 8开始,您可以并且应该通过将其isActive
属性设置为来激活约束true
.这使约束能够将自己添加到正确的视图中.您可以通过传递包含约束的数组来一次激活多个约束NSLayoutConstraint.activate()
let label = UILabel(frame: CGRect.zero)
label.text = "Nothing to show"
label.textAlignment = .center
label.backgroundColor = .red // Set background color to see if label is centered
label.translatesAutoresizingMaskIntoConstraints = false
self.tableView.addSubview(label)
let widthConstraint = NSLayoutConstraint(item: label, attribute: .width, relatedBy: .equal,
toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 250)
let heightConstraint = NSLayoutConstraint(item: label, attribute: .height, relatedBy: .equal,
toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 100)
let xConstraint = NSLayoutConstraint(item: label, attribute: .centerX, relatedBy: .equal, toItem: self.tableView, attribute: .centerX, multiplier: 1, constant: 0)
let yConstraint = NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: self.tableView, attribute: .centerY, multiplier: 1, constant: 0)
NSLayoutConstraint.activate([widthConstraint, heightConstraint, xConstraint, yConstraint])
Run Code Online (Sandbox Code Playgroud)
改善方案:
由于最初回答了这个问题,因此引入了布局锚点,使得创建约束变得更加容易.在这个例子中,我创建约束并立即激活它们:
label.widthAnchor.constraint(equalToConstant: 250).isActive = true
label.heightAnchor.constraint(equalToConstant: 100).isActive = true
label.centerXAnchor.constraint(equalTo: self.tableView.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: self.tableView.centerYAnchor).isActive = true
Run Code Online (Sandbox Code Playgroud)
注意:在创建和激活约束之前,始终将子视图添加到视图层次结构中.
原答案:
约束参考NSLayoutConstraint.activate()
.由于您self.tableView
要将标签添加为子视图,因此需要将约束添加到"共同祖先":
NSLayoutConstraint.activate([
label.widthAnchor.constraint(equalToConstant: 250),
label.heightAnchor.constraint(equalToConstant: 100),
label.centerXAnchor.constraint(equalTo: self.tableView.centerXAnchor),
label.centerYAnchor.constraint(equalTo: self.tableView.centerYAnchor)
])
Run Code Online (Sandbox Code Playgroud)
正如@mustafa和@kcstricks在评论中指出的那样,你需要设置 self.tableView
为label.translatesAutoresizingMaskIntoConstraints
.当你这样做,你还需要指定false
,并width
因为框架不再使用有约束的标签.最后,您还应将其设置为height
以textAlignment
使文本在标签中居中.
self.tableView.addConstraint(xConstraint)
self.tableView.addConstraint(yConstraint)
Run Code Online (Sandbox Code Playgroud)
Sur*_*gch 32
下面的代码与Interface Builder中的中心完全相同.
override func viewDidLoad() {
super.viewDidLoad()
// set up the view
let myView = UIView()
myView.backgroundColor = UIColor.blue
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
// Add code for one of the constraint methods below
// ...
}
Run Code Online (Sandbox Code Playgroud)
方法1:锚式
myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
Run Code Online (Sandbox Code Playgroud)
方法2:NSLayoutConstraint样式
NSLayoutConstraint(item: myView, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: myView, attribute: NSLayoutConstraint.Attribute.centerY, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view, attribute: NSLayoutConstraint.Attribute.centerY, multiplier: 1, constant: 0).isActive = true
Run Code Online (Sandbox Code Playgroud)
NSLayoutConstraint
Style 的首选方法,但它仅适用于iOS 9,所以如果你支持iOS 8,那么你仍然应该使用NSLayoutConstraint
Style.小智 10
ObjectiveC等价物是:
myView.translatesAutoresizingMaskIntoConstraints = NO;
[[myView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor] setActive:YES];
[[myView.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor] setActive:YES];
Run Code Online (Sandbox Code Playgroud)
以编程方式,您可以通过添加以下约束来完成此操作.
NSLayoutConstraint *constraintHorizontal = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.superview
attribute:attribute
multiplier:1.0f
constant:0.0f];
NSLayoutConstraint *constraintVertical = [NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self.superview
attribute:attribute
multiplier:1.0f
constant:0.0f];
Run Code Online (Sandbox Code Playgroud)
在 Swift 5 中,它看起来像这样:
label.translatesAutoresizingMaskIntoConstraints = false
label.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor).isActive = true
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
83295 次 |
最近记录: |