0

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

Nikita Alexander
  • 527
  • 6
  • 11
  • Hey - have you added any constraints in the headerView? – Vikram Parimi Sep 09 '22 at 14:42
  • Also have you set headerView.translatesAutoresizingMaskIntoConstraints = false? – Vikram Parimi Sep 09 '22 at 14:49
  • You've said *"My header view layout isn't working"* ... but you haven't shown us **your header view layout**. – DonMag Sep 09 '22 at 15:30
  • @VikramParimi I'm building my UI in Interface Builder, so .translatesAutoresizingMaskIntoConstraints is false by default. I'm adding the images programmatically, so I tried applying it and it just makes the images gigantic, but it didn't help with the label margins. – Nikita Alexander Sep 09 '22 at 17:16
  • @DonMag my header view UI is mostly built in Interface Builder, only the images are added programmatically, so I omitted the code (which is just setting date, username etc.) for simplicity sake – Nikita Alexander Sep 09 '22 at 17:25
  • @NikitaAlexander - *"my header view UI is mostly built in Interface Builder"* -- yes... so we need to see how you have designed that view. What elements are in it? How are they constrained? Etc. – DonMag Sep 09 '22 at 17:41
  • @DonMag I added screenshots of the header view design in the Interface Builder and the specifics of my description label with the details pane on the right. – Nikita Alexander Sep 09 '22 at 18:09
  • @NikitaAlexander - please show your layout like this: https://i.stack.imgur.com/nP3rw.png - so we can see all of your elements and constraints. In your comment you say *"the images are added programmatically"* but it's not at all clear where any image views are. – DonMag Sep 09 '22 at 18:21

1 Answers1

0

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

}

Vikram Parimi
  • 777
  • 6
  • 29
  • Unfortunately setting translatesAutoresizingMaskIntoConstraints to true tends to do nothing, the huge label margins still persist – Nikita Alexander Sep 10 '22 at 06:03
  • Have you tried setting the vertical content hugging for the header label to 750 or 1000? – Vikram Parimi Sep 10 '22 at 14:58
  • I seemed to have figured out the problem, it's due to the UIScrollView aspect ratio of 1:1 to keep it square. If I delete it, the images get huge vertical height, the same height that amounts for the label margins, but the label gets the correct height needed. I haven't yet managed to find a way around it to keep the images square, although I tried to manually set it's frame and size. – Nikita Alexander Sep 12 '22 at 13:09
  • have you set the constraints to your scrollview? Aligned to its superview – Vikram Parimi Sep 12 '22 at 13:27
  • Yes, they were set and aligned to the superview. I managed to find a solution by setting width and height constraints to the UIScrollView and then programmatically updating them to reflect the width of the device's screen. It works, but I'm not sure if this qualifies as an answer. – Nikita Alexander Sep 12 '22 at 13:51
  • If you set the width to it superview there shouldn't be a need to re-update the width to match screen size. Could you share a few more details? – Vikram Parimi Sep 12 '22 at 21:04
  • You're right, there's no need to do it since I could set the width to the superview sides, but I did it anyway, what matters is the height constraint though. – Nikita Alexander Sep 13 '22 at 13:13