0

In my app I have an UITableView with a header created with .xib, this is the class:

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

I'm adding it to tableHeaderView:

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

This is the .xib with just one label and its relative constraints. enter image description here

That's the result if I run on simulator (same on device)

enter image description here

I can't understand why the height is bigger than 21. With the "Debug View Hierarchy" I can see that is not using the label height but the UIView-Encapsulated-Layout-Height

Console log:

    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.
Federico Malagoni
  • 722
  • 1
  • 7
  • 21

2 Answers2

0

You can give lower priority to the bottom spacing constraint and higher priority to height constraint

KSRK
  • 31
  • 2
  • It gives the same result – Federico Malagoni Mar 28 '19 at 16:29
  • 1
    Try this let hSize = viewHomeHeader.systemLayoutSizeFitting(UILayoutFittingCompressedSize) let height = hSize.height var frame = viewHomeHeader.frame frame.size.height = height viewHomeHeader.frame = frame self.tableHeaderView = viewHomeHeader – KSRK Mar 28 '19 at 16:44
0

As specified in the documentation:

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.

So you have to set the header size before setting it.

If your header has a height which depends on its content, here is a possible solution:

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

Wait viewDidLayoutSubviews() to get the actual size of the view.

If your content is static, simply set its height:

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

Note that the header's autoresizingMask should not contain flexibleHeight (check your xib). The header should keep the height specified.

GaétanZ
  • 4,870
  • 1
  • 23
  • 30