在代码中设置 IBOutlet 的自动布局约束
Setting Auto Layout constraints of IBOutlet in code
如果我有一个 IBOutlet 的 UILabel,为什么我不能只在代码中设置它的自动布局约束而不必在 Storyboard 中设置至少一个约束?
例如,假设我有一个在情节提要中没有设置约束的 IBOutlet UILabel,我尝试将它置于 superview 的中心:
override func viewDidLoad() {
super.viewDidLoad()
self.label.setTranslatesAutoresizingMaskIntoConstraints(false)
self.label.centerInSuperview()
}
然后我有一个 UIView 扩展来处理自动布局代码如下:
extension UIView {
func centerInSuperview() {
self.centerVerticallyInSuperview()
self.centerHorizontallyInSuperview()
}
func centerVerticallyInSuperview() {
self.superview?.addConstraint(NSLayoutConstraint(
item: self,
attribute: NSLayoutAttribute.CenterY,
relatedBy: NSLayoutRelation.Equal,
toItem: self.superview,
attribute: NSLayoutAttribute.CenterY,
multiplier: 1,
constant: 0))
}
func centerHorizontallyInSuperview() {
self.superview?.addConstraint(NSLayoutConstraint(
item: self,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: self.superview,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1,
constant: 0))
}
}
如果 UILabel 是从以下代码创建的,则上述代码可以正常工作:
var label = UILabel()
label.text = "Label"
self.view.addSubview(label)
label.setTranslatesAutoresizingMaskIntoConstraints(false)
label.centerInSuperview()
但是如果 UILabel 是一个没有在情节提要中设置约束的出口,它就不起作用。奇怪的是,如果 outlet 在情节提要中设置了一个随机约束(比如 top space 到 superview),那么它也可以工作。
如果故事板或 NIB 启用了自动布局,Xcode 将不允许视图缺少约束。 Select 视图并调出尺寸检查器。您会看到一条注释,大意是 "The selected views have no constraints. At build time, explicit left, top, width, and height constraints will be generated for the view."
一般来说,Xcode会提供约束以消除布局中的歧义。
您可以通过向视图添加足够的约束但将它们标记为占位符(在构建时删除)来解决此问题。这将使视图不受约束。
您还可以添加约束、设置约束的出口并在添加其他约束之前以编程方式删除它们。
如果我有一个 IBOutlet 的 UILabel,为什么我不能只在代码中设置它的自动布局约束而不必在 Storyboard 中设置至少一个约束?
例如,假设我有一个在情节提要中没有设置约束的 IBOutlet UILabel,我尝试将它置于 superview 的中心:
override func viewDidLoad() {
super.viewDidLoad()
self.label.setTranslatesAutoresizingMaskIntoConstraints(false)
self.label.centerInSuperview()
}
然后我有一个 UIView 扩展来处理自动布局代码如下:
extension UIView {
func centerInSuperview() {
self.centerVerticallyInSuperview()
self.centerHorizontallyInSuperview()
}
func centerVerticallyInSuperview() {
self.superview?.addConstraint(NSLayoutConstraint(
item: self,
attribute: NSLayoutAttribute.CenterY,
relatedBy: NSLayoutRelation.Equal,
toItem: self.superview,
attribute: NSLayoutAttribute.CenterY,
multiplier: 1,
constant: 0))
}
func centerHorizontallyInSuperview() {
self.superview?.addConstraint(NSLayoutConstraint(
item: self,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: self.superview,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1,
constant: 0))
}
}
如果 UILabel 是从以下代码创建的,则上述代码可以正常工作:
var label = UILabel()
label.text = "Label"
self.view.addSubview(label)
label.setTranslatesAutoresizingMaskIntoConstraints(false)
label.centerInSuperview()
但是如果 UILabel 是一个没有在情节提要中设置约束的出口,它就不起作用。奇怪的是,如果 outlet 在情节提要中设置了一个随机约束(比如 top space 到 superview),那么它也可以工作。
如果故事板或 NIB 启用了自动布局,Xcode 将不允许视图缺少约束。 Select 视图并调出尺寸检查器。您会看到一条注释,大意是 "The selected views have no constraints. At build time, explicit left, top, width, and height constraints will be generated for the view."
一般来说,Xcode会提供约束以消除布局中的歧义。
您可以通过向视图添加足够的约束但将它们标记为占位符(在构建时删除)来解决此问题。这将使视图不受约束。
您还可以添加约束、设置约束的出口并在添加其他约束之前以编程方式删除它们。