UITableView 页脚高度问题

UITableViewFooter height issue

在我的应用程序中,我有一个 UITableView 和一个使用 .xib 创建的 header,这是 class:

class ViewHomeHeader: UIView {
    class func instanceFromNib() -> ViewHomeHeader {
        return UINib(nibName: "ViewHomeHeader", bundle: nil).instantiate(withOwner: self, options: nil).first as! ViewHomeHeader
    }
}

我正在将它添加到 tableHeaderView:

let viewHomeHeader = ViewHomeHeader.instanceFromNib()
tableView.tableHeaderView = viewHomeHeader

这是只有一个标签及其相关限制的 .xib。

这就是我在模拟器上 运行 的结果(在设备上也是如此)

我不明白为什么身高比21还大。 使用 "Debug View Hierarchy" 我可以看到不是使用标签高度而是 UIView-Encapsulated-Layout-Height

控制台日志:

    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. 
(
    "<NSLayoutConstraint:0x28079f9d0 UILabel:0x104529b80'Label'.height == 21   (active)>",
    "<NSLayoutConstraint:0x2807ac0a0 UILayoutGuide:0x281d9d500'UIViewSafeAreaLayoutGuide'.bottom == UILabel:0x104529b80'Label'.bottom + 17   (active)>",
    "<NSLayoutConstraint:0x2807ac140 UILabel:0x104529b80'Label'.top == UILayoutGuide:0x281d9d500'UIViewSafeAreaLayoutGuide'.top + 18   (active)>",
    "<NSLayoutConstraint:0x2807ae490 'UIView-Encapsulated-Layout-Height' Jordy.ViewHomeHeader:0x104529790.height == 143   (active)>",
    "<NSLayoutConstraint:0x2807ac000 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x281d9d500'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':Jordy.ViewHomeHeader:0x104529790 )>",
    "<NSLayoutConstraint:0x28079fc50 'UIViewSafeAreaLayoutGuide-top' V:|-(0)-[UILayoutGuide:0x281d9d500'UIViewSafeAreaLayoutGuide']   (active, names: '|':Jordy.ViewHomeHeader:0x104529790 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x28079f9d0 UILabel:0x104529b80'Label'.height == 21   (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.

您可以为底部间距约束赋予较低优先级,为高度约束赋予较高优先级

如文档中所述:

When assigning a view to this property, set the height of that view to a nonzero value. The table view respects only the height of your view's frame rectangle; it adjusts the width of your header view automatically to match the table view's width.

所以在设置之前必须先设置header大小

如果您的 header 的高度取决于其内容,这里是一个可能的解决方案:

let header = HeaderView()
let widthConstraint = header.widthAnchor.constraint(equalToConstant: view.bounds.width)
header.translatesAutoresizingMaskIntoConstraints = false
widthConstraint.isActive = true
let targetSize = header.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
header.frame.size.height = targetSize.height
widthConstraint.isActive = false
header.translatesAutoresizingMaskIntoConstraints = true
tableView.tableHeaderView = header

等待 viewDidLayoutSubviews() 获取 view 的实际大小。

如果您的内容是静态的,只需设置其高度:

let header = HeaderView()
header.frame.size.height = 30
tableView.tableHeaderView = header

请注意 header 的 autoresizingMask 不应包含 flexibleHeight(检查您的 xib)。 header 应保持指定的高度。