使用自动布局和 systemLayoutSizeFittingSize

Using auto layout and systemLayoutSizeFittingSize

我有一个非常简单的观点,即我无法终生解决问题。我已经成功地将自动布局和 systemLayoutSizeFittingSize 用于相当复杂的自定义 UITableViewCells。这是我第一次将它用于 UIView(用于 UITableView.tableHeaderView),我无法让它工作。

我在视图中有一个简单的标签,我想覆盖整个视图。我已将 TrailingLeadingTopBottom 约束添加到标签中,以对抗父项的相应边。当我这样做时,systemLayoutSizeFittingSize 计算出正确的 height,但我得到以下错误:

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) 
(
    "<NSLayoutConstraint:0x7fbb71d9a310 V:|-(5)-[UILabel:0x7fbb71df5120'Test Label']   (Names: '|':mailapp.MailTableHeaderView:0x7fbb71d2c490 )>",
    "<NSLayoutConstraint:0x7fbb71d2ebf0 UILabel:0x7fbb71df5120'Test Label'.bottom == app.HeaderView:0x7fbb71d2c490.bottom - 5>",
    "<NSLayoutConstraint:0x7fbb71de31d0 V:[app.HeaderView:0x7fbb71d2c490(0)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fbb71d2ebf0 UILabel:0x7fbb71df5120'Test Label'.bottom == app.HeaderView:0x7fbb71d2c490.bottom - 5>

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

现在,如果我删除标签上的 "bottom" 约束,自动布局可以正常工作,但现在 systemLayoutSizeFittingSize returns 0.

什么是既能使约束满足自动布局引擎又能systemLayoutSizeFittingSize计算正确大小的正确方法?

正如我提到的,最令人困惑的是我已经成功地将其用于复杂的自动布局,但我注意到所有这些都是 UITableViewCells。我不确定是否有区别。

根据 Apple Visual Format Language,以下内容似乎在您的 HeaderView 上设置了“0”高度限制。

例如

"<NSLayoutConstraint:0x7fbb71de31d0 V:[app.HeaderView:0x7fbb71d2c490(0)]>"

我会首先对此进行调查,因为高度为 0 可能会扰乱顶部和底部间距的其他标签约束。

我想出了问题,但我不明白为什么。对于 UITableViewHeader,我无法为视图执行典型的自动布局操作。也就是说,我必须将 translatesAutoresizingMaskIntoConstraints 设置为 true。实际上,我无法为 header 视图使用自动布局,我必须手动设置框架。

在 header 视图中,我可以成功地为子视图使用自动布局。

所以我的算法是这样构建 tableHeaderView:

  • 使用任意帧创建 header 视图
  • 计算约束(header 视图的子视图)
  • 设置 header 视图的 frame.width 以匹配 parent tableView.frame.width
  • 布局 header 视图
  • 使用systemLayoutSizeFittingSize计算高度
  • 更新 header 视图的 frame.height

这对我有用。如果我创建 header 视图并将 translatesAutoresizingMaskIntoConstraints 设置为 false.

,我将无法使用它