【问题标题】:When should translatesAutoresizingMaskIntoConstraints be set to true?何时应将 translatesAutoresizingMaskIntoConstraints 设置为 true?
【发布时间】:2018-05-27 18:24:39
【问题描述】:

我读过documentation。但我仍然不确定何时不需要将其设置为false。在下面的代码中,如果我将其设置为false,我将根本看不到标题。如果我将其保留为true,那么一切都很好。

View 调试层次结构中的以下内容将给出警告“width and position are ambiguous”。

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let header = UIView()
    header.translatesAutoresizingMaskIntoConstraints = false
    header.backgroundColor = .orange
    header.heightAnchor.constraint(equalToConstant: 10).isActive = true

    return header
}

我想每当我需要修改代码中的任何内容时,我都必须将 translatesAutoresizingMaskIntoConstraints 设置为 false

也许更正确的说法是,如果您需要删除所有约束,然后将其设置为 false,然后添加您喜欢的内容,在这种情况下,您需要为所有 4 个面添加约束。

但是,如果您只需要保留系统提供给您的内容,在这种情况下,将由 tableView 管理其位置和宽度,然后留给true

是吗?

【问题讨论】:

  • 如果将其设置为false,则框架将被忽略,定位和大小必须完全由NSLayoutConstraints 指定。如果设置为true,那么frame会被iOS翻译成约束。
  • @vacawama 如果我将其设置为true 我自己添加的约束会发生什么?此外,向viewForHeaderInSection 添加约束的推荐方法是什么?
  • 如果它设置为true,并且您添加了自己的约束,您将遇到约束冲突,系统将做出最好的猜测使用哪些,您可能会很幸运并且它似乎有效,但对客户来说肯定会失败!
  • @vacawama 如果您在 cmets 中提供了解决方案,我不明白:/ 您说这可能会造成冲突。那么我该如何为此添加高度约束呢? (我不想使用框架,因为我希望你使用动态标题高度。)
  • 也许this 会有所帮助。

标签: ios swift uitableview autolayout nslayoutconstraint


【解决方案1】:

translatesAutoresizingMaskIntoConstraints 需要在以下情况下设置为 false:

  1. 您在代码中创建一个基于UIView 的对象(如果文件启用了自动布局,Storyboard/NIB 将为您设置它),
  2. 并且您希望对此视图使用自动布局,而不是基于框架的布局,
  3. 并且视图将被添加到使用自动布局 的视图层次结构中。

在这种情况下,并非所有这些都是正确的。具体来说,第2点。

在您从viewForHeaderInSection 返回标题视图后,它会添加到表格视图中,并且其frame 是根据表格视图的当前宽度和您从heightForHeaderInSection 返回的高度设置的。

您可以将子视图添加到根标题视图(代码中的header)并使用约束来相对于标题视图布局这些子视图。

您已经发现了无法在 cmets 中对标题视图本身使用自动布局的原因;在您创建视图时,它还不是视图层次结构的一部分,因此您不能将其边缘限制为任何东西。

为了获得动态标题大小,您需要将子视图添加到您的header 视图并在这些子视图和header 之间添加约束。然后,自动布局可以使用header 的内在内容大小来确定标题视图大小。

由于您没有限制header 的框架,因此不要将translatesAutoresizingMaskIntoConstraints 设置为false。您需要确保对自动布局的子视图有足够的约束,以确定header 的大小。

如果子视图的内在内容大小不足,您将需要从上到下的连续约束线,并且可能需要对子视图进行一些高度约束。

你添加到header的任何子视图需要将translatesAutoresizingMaskIntoConstraints设置为false

您还需要从 estimatedHeightForHeaderInSection 返回 something - 越接近实际标题高度越好 - 如果您使用的是 tableview.sectionHeaderHeight = UITableViewAutomaticDimension

【讨论】:

  • 有趣。所以大多数答案,包括来自this highly viewed question 的接受答案我猜都是误导
  • 实际上我只是命令点击了UITableViewAutomaticDimension,这些是 cmets: "// 从 tableView:heightForHeaderInSection: 或 tableView:heightForFooterInSection: 返回这个值导致高度适合从 / 返回的值/ tableView:titleForHeaderInSection: 或 tableView:titleForFooterInSection: 如果标题不为零。"
  • 对不起,我已经澄清了我的答案的最后一段;您不能为 header 视图使用自动布局,但您可以为该视图中的子视图使用自动布局,然后它应该适合您。
  • 我现在看到的方式是:使用翻译后的约束,标题被从所有 4 个边缘约束到其父视图。如果我将标头本身的translatesAutoResizingMaskIntoConstraints 设置为false,所有这些都将被删除。但我需要它们,所以我必须保留它true然后我正在为其子视图添加更多约束。对于这些子视图,它们都需要将translatesAutoResizingMaskIntoConstraints 设置为false,它们添加到标题的任何约束都不会与翻译后的约束冲突...
  • 没错。 tableview 将处理header 视图所需的任何约束(或直接设置它的框架,这对你无关紧要)
【解决方案2】:
  • 对于以编程方式创建的视图,默认值为 true,对于 Interface Builder 的视图默认为 false

    如果该属性为(或设置为)True,系统会根据视图的框架及其自动调整大小掩码自动创建一组约束。如果您添加自己的约束,它们不可避免地会与自动生成的约束冲突。这会造成无法令人满意的布局。因此,当以编程方式实例化视图时,请务必将其 translatesAutoresizingMaskIntoConstraints 属性设置为 NO

【讨论】:

  • “当以编程方式实例化视图时,请务必将它们的 translatesAutoresizingMaskIntoConstraints 属性设置为 NO” - 实际上,并非总是如此,但仅当您想创建自己的约束来处理自动布局时。如果您更喜欢处理帧,则不应将此值设置为 false :)
【解决方案3】:

有了PANKAJ VERMAanswer,它终于有意义了。

就我而言,我有一个 ImageView 并且只设置了 2 个约束,但错误表明我有更多约束并且 LayoutConstraints 无法同时满足约束

        view.addSubview(imageView)
        let yConstraint = imageView.centerYAnchor.constraint(equalTo: layout.centerYAnchor)
        yConstraint.identifier = "yConstraint"
        let xConstraint = imageView.centerXAnchor.constraint(equalTo: layout.centerXAnchor)
        xConstraint.identifier = "xConstraint"

错误信息:

[LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x600000089360 h=--& v=--& UIImageView:0x7fc1782087b0.minY == 0   (active, names: '|':UIView:0x7fc176406220 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x600000089220 h=--& v=--& UIImageView:0x7fc1782087b0.height == 0   (active)>",
    "<NSLayoutConstraint:0x600000088c30 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600001a880e0'UIViewLayoutMarginsGuide']-(34)-|   (active, names: '|':UIView:0x7fc176406220 )>",
    "<NSLayoutConstraint:0x600000088cd0 'UIView-topMargin-guide-constraint' V:|-(48)-[UILayoutGuide:0x600001a880e0'UIViewLayoutMarginsGuide']   (active, names: '|':UIView:0x7fc176406220 )>",
    "<NSLayoutConstraint:0x600000088d70 'yConstraint' UIImageView:0x7fc1782087b0.centerY == UILayoutGuide:0x600001a880e0'UIViewLayoutMarginsGuide'.centerY   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600000088d70 'yConstraint' UIImageView:0x7fc1782087b0.centerY == UILayoutGuide:0x600001a880e0'UIViewLayoutMarginsGuide'.centerY   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

我设置的第二个约束 ("xConstraint") 基本上有一个几乎相同的错误日志。正如您在错误日志中看到的那样,我“过度约束”了我的 UI。除了'yConstraint',我还有其他 4 个限制条件。我相信约束在一个 tuple 中,因此它们周围的括号。 XCode 试图通过提示“(注意:如果您看到不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档)”来提供帮助,但我个人认为这没有足够的帮助。


什么是“自动调整大小蒙版”?

我想知道这意味着什么很重要,因为它被转换为约束,因此命名为translatesAutoresizingMaskIntoConstraints。 它是 UIView 的一个实例属性,包含一个整数位掩码。它保留了一些位,您可以打开和关闭“灵活左边距”和“灵活高度”等功能(其中更多here)。

当视图的边界发生变化时,该视图会根据每个子视图的自动调整大小掩码自动调整其子视图的大小。

source

总结一下自动调整蒙版,它保留了您想要的自动调整大小功能,例如灵活的高度和宽度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多