在代码中设置 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 约束的主要内容,如果未能解决你的问题,请参考以下文章

在代码中设置 ColumnDefinitions

如何使用 Eloquent 在 Laravel 中设置 AUTO_INCREMENT?

如何在 BottomNavigationView 中设置所选项目

百度编辑器中设置表格居中

从 NIB 加载后 IBOutlet 实例为(空)

使用条件在 smarty 中设置 var