什么时候应该将 translatesAutoresizingMaskIntoConstraints 设置为 true?

When should translatesAutoresizingMaskIntoConstraints be set to true?

我已阅读 documentation。但是我仍然不确定什么时候不需要将它设置为 false。在下面的代码中,如果我将其设置为 false,我将根本看不到 header。如果我将它保留为 true,那么一切都很好。

下面在View debug hierarchy中会给出警告“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

对吗?

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

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

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

在您 return 之后,viewForHeaderInSection 的 header 视图被添加到 table 视图,并且其 frame 是根据当前宽度设置的table 视图的高度和 return 来自 heightForHeaderInSection 的高度。

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

您已经在评论中找到了 header 视图本身不能使用自动布局的原因;在您创建视图时,它还不是视图层次结构的一部分,因此您不能将其边缘限制为任何内容。

为了动态调整 header 大小,您需要向 header 视图添加子视图,并在这些子视图和 header 之间添加约束。然后,自动布局可以使用 header 的固有内容大小来确定 header 视图大小。

因为你没有约束header的框架,所以不要将translatesAutoresizingMaskIntoConstraints设置为false。您将需要确保对自动布局的子视图有足够的约束,以确定 header.

的大小

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

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

你还需要 return estimatedHeightForHeaderInSection 的东西 - 越接近你的实际 header 身高越好 - 如果你正在使用tableview.sectionHeaderHeight = UITableViewAutomaticDimension

  • 对于以编程方式创建的视图,默认值为 true 并且对于 Interface Builder 默认的视图是 false

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

有了PANKAJ VERMA,终于明白了。

在我的例子中,我有一个 ImageView 并且只设置了 2 个约束,但是错误显示我有更多的约束并且 LayoutConstraints 是 Unable to simultaneously satisfy constraints :

        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") 基本上有一个几乎相同的错误日志。正如您在错误日志中看到的,我是“over-constraining”我的UI。除了 'yConstraint',我还有 4 个其他约束。我相信约束在 元组 中,因此在它们周围有括号。 XCode 尝试通过提示“(注意:如果您看到您不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档)”,但是我个人认为这不够有用。


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

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

When a view’s bounds change, that view automatically resizes its subviews according to each subview’s autoresizing mask.

source

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