在代码中设置 IBOutlet 的 Auto Layout 约束
Posted
技术标签:
【中文标题】在代码中设置 IBOutlet 的 Auto Layout 约束【英文标题】:Setting Auto Layout constraints of IBOutlet in code 【发布时间】:2015-03-29 23:39:33 【问题描述】:如果我有一个 IBOutlet 的 UILabel,为什么我不能在代码中设置它的自动布局约束,而不必在 Storyboard 中设置至少一个约束?
例如,假设我有一个未在情节提要中设置约束的 IBOutlet UILabel,我尝试将其置于超级视图的中心:
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 是一个没有在情节提要中设置约束的插座,它就不起作用。奇怪的是,如果插座在情节提要中设置了一个随机约束(例如顶部空间到超级视图),那么它也可以工作。
【问题讨论】:
您是否对您放置在情节提要上的 UI 元素调用setTranslatesAutoresizingMaskIntoConstraints(false)
?或者只是给你的centerInSuperview()
打电话?
@nhgrif 我已经尝试过使用和不使用 setTranslates 调用。都不行。
那是因为如果你不这样做,系统会为你添加约束,这些约束会与你的冲突。查看 Size Inspector 中“constraints”下的内容,了解您尚未为其添加约束的视图。
@rdelmar 这是否意味着我需要在设置自己的代码之前删除所有约束?当我在 Size Inspector 中查看我没有添加约束的标签时,它说“选定的视图没有约束。在构建时,将为视图生成显式的左侧、顶部、宽度和高度约束。”
首先,我想说如果您不打算添加约束,为什么还要在 IB 中添加视图;只需在代码中创建它。如果你真的想在 IB 中添加它,那么添加你自己的约束,并在编辑约束时勾选“在构建时删除”框。
【参考方案1】:
如果情节提要或 NIB 启用了自动布局,Xcode 将不允许视图缺少约束。选择视图并调出尺寸检查器。您将看到一条注释,大意是“选定的视图没有约束。在构建时,将为视图生成显式的左、上、宽和高约束。”
一般来说,Xcode 会提供约束来消除布局中的歧义。
您可以通过向视图添加足够的约束但将它们标记为占位符(在构建时删除)来解决此问题。这将使视图不受约束。
您还可以添加约束,设置约束的出口,并在添加其他约束之前以编程方式删除它们。
【讨论】:
以上是关于在代码中设置 IBOutlet 的 Auto Layout 约束的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Eloquent 在 Laravel 中设置 AUTO_INCREMENT?