Dynamic height for UITableView header view - Problem with huge margins

Viewed 47

In my application I have a UITableViewController that allows preview of a photo and description to that photo, which are both contained in the UITableView's header. The description label needs to be multiline-compatible, so the lines amount is set to 0, obviously the next problem is to make the UITableView header dynamically resizable to adjust it's size to the amount of text in the description label.

The description label is set to fit it's content with self.descriptionLabel.sizeToFit()

The UITableView header view is also set to dynamically resize to fit it's contents via the widely accepted answer from this post:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        if let headerView = tableView.tableHeaderView {
            
            let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
            var headerFrame = headerView.frame
            
            //Comparison necessary to avoid infinite loop
            if height != headerFrame.size.height {
                headerFrame.size.height = height
                headerView.frame = headerFrame
                tableView.tableHeaderView = headerView
            }
        }
}

This solution resizes the UITableView header view, but for some reason gives my description label absolutely huge margins stretching up and down from the text. I highlighted my description label with self.descriptionLabel.backgroundColor = .red to be sure it's the description label that stretches and that indeed seems to be the case. I tried a multitude of other solutions, but this is the only one that actually at least resizes the UITableView header view, so I'm stuck with this at the moment.

The margins, however, are absolutely enormous and I can't find a solution to make them fit the description label text size. Any help will be greatly appreciated, because I can't get my head around it.

I added screenshots displaying the problem at the end of this post. enter image description here

This is the top of the UITableView header, with the red displaying the UILabel beginning to stretch down

enter image description here

This is the actual text of the UILabel

enter image description here And finally this is where the UILabel stretching finishes with the UIButton at the bottom. I am at a complete loss of how to fix this.

enter image description here This is my header view UI in Interface Builder

enter image description here And these are the detailed constraints of my description label in Interface Builder

1 Answers

I believe since the translatesAutoresizingMaskIntoConstraints ARE set to false for the headerView the layout is not auto adjusted once it's calculated in layoutSubviews method.

Try setting the translatesAutoresizingMaskIntoConstraints to true to set the headerView height properly as below:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    if let headerView = tableView.tableHeaderView {
        
        let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
        var headerFrame = headerView.frame
        
        //Comparison necessary to avoid infinite loop
        if height != headerFrame.size.height {
            headerFrame.size.height = height
            headerView.frame = headerFrame
            tableView.tableHeaderView = headerView
        }
    }
    translatesAutoresizingMaskIntoConstraints = true

}

Related