- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个 UITableViewController,如果没有任何内容可显示,它不会显示任何部分。我添加了一个标签来向用户表明此代码没有任何可显示的内容:
label = UILabel(frame: CGRectMake(20, 20, 250, 100))
label.text = "Nothing to show"
self.tableView.addSubview(label)
但是现在,我希望它水平和垂直居中。通常,我会选择屏幕截图中突出显示的两个选项(加上高度和宽度的选项):
我已尝试使用以下代码添加约束,但应用程序因错误而崩溃:
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)
错误:
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
标签应始终水平和垂直居中,因为该应用支持设备旋转。
我做错了什么?如何成功添加这些约束?
谢谢!
最佳答案
Swift 3/Swift 4 更新:
从 iOS 8 开始,您可以并且应该通过将约束的 isActive
属性设置为 true
来激活您的约束。这使约束能够将自己添加到正确的 View 中。您可以通过将包含约束的数组传递给 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])
更好的解决方案:
由于最初回答了这个问题,因此引入了布局 anchor ,使创建约束变得更加容易。在这个例子中,我创建了约束并立即激活它们:
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
或者同样使用 NSLayoutConstraint.activate()
:
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)
])
注意:始终在创建和激活约束之前将您的 subview 添加到 View 层次结构中。
原答案:
约束引用了 self.tableView
。由于您将标签添加为 self.tableView
的 subview ,因此需要将约束添加到“共同祖先”:
self.tableView.addConstraint(xConstraint)
self.tableView.addConstraint(yConstraint)
正如@mustafa 和@kcstricks 在评论中指出的,您需要将label.translatesAutoresizingMaskIntoConstraints
设置为false
。执行此操作时,还需要指定带约束的标签的 width
和 height
,因为不再使用框架。最后,您还应该将 textAlignment
设置为 .Center
,以便您的文本在标签中居中。
var label = UILabel(frame: CGRectZero)
label.text = "Nothing to show"
label.textAlignment = .Center
label.backgroundColor = UIColor.redColor() // 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)
label.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: label, attribute: .Height, relatedBy: .Equal,
toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 100)
label.addConstraint(heightConstraint)
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)
self.tableView.addConstraint(xConstraint)
self.tableView.addConstraint(yConstraint)
关于ios - 以编程方式添加 CenterX/CenterY 约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27624133/
我有一个 UITableViewController,如果没有任何内容可显示,它不会显示任何部分。我添加了一个标签来向用户表明此代码没有任何可显示的内容: label = UILabel(frame:
我正在尝试制作一个自定义 UICollectionView 单元类。该单元格由内容 View 和标签组成。我希望标签位于 View 的水平和垂直中心,但标签放置在内容 View 的中心 y 轴上方。
我读过一个旋转变换,该变换支持使用 rotate(angle, centerX, centerY) 围绕中心点旋转,但它在通过 CSS 应用时似乎不起作用。 它作为一个属性内联工作:
我是一名优秀的程序员,十分优秀!