0

I'm trying to change the height of a particular section header inside a table view. I tested with code below just to understand how tableView(_:heightForHeaderInSection:) works.

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    print("DEBUG : ", section, tableView.sectionHeaderHeight)
    return tableView.sectionHeaderHeight
}

Debug print below shows that the method is called multiple times, but that the header height is always 18.0 (which is default).

DEBUG :  4 18.0
DEBUG :  4 18.0
DEBUG :  0 18.0
DEBUG :  0 18.0
DEBUG :  1 18.0
DEBUG :  1 18.0
DEBUG :  2 18.0
...
DEBUG :  3 18.0

Now, as soon as I use 18.0 as fix value for return (for testing purpose), the vertical extend of the table view is visually compressed, id est the sections are closer together, and the entire UI looks therefore different. It seems that the space between the sections is reduced, since the header of the first section is (vertically) only half visible.

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    print("DEBUG : ", section, tableView.sectionHeaderHeight)
    return 18.0
}

How is that possible?
Possibly a bug?

--- UPDATE --- (13.06.2019)

My question was based on the intention to hide a section (2) including header. I realized that tableView.sectionHeaderHeight was the wrong property to use. I should have used super.tableView(tableView, heightForHeaderInSection: section).

The code below works as desired:

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if (section == 2) && myCondition {
        return CGFloat.leastNonzeroMagnitude
    }
    return super.tableView(tableView, heightForHeaderInSection: section)
}

Nevertheless, I don't know where the 18.0 (see above) comes from since I don't use .xib files.

BTW super.tableView(tableView, heightForHeaderInSection: section) always returns -1. I believe this makes iOS decide on its own which heigth to choose. The manually set 18.0 (for testing) made the header shrink since the iOS chosen automatic value for the header height is higher.

I didn't find a property to print this value (must be around 30.0 - a wild guess, nothing more).

geohei
  • 696
  • 4
  • 15
  • can you show the viewForHeader? – Alastar May 31 '19 at 07:23
  • please use estimatedHeight method too I think it solve your issue – Yogesh Patel May 31 '19 at 07:24
  • @Alastar - Do you mean a screenshot? – geohei May 31 '19 at 07:54
  • No, your viewForHeader method, if you have any custom view created for each header. – AjinkyaSharma May 31 '19 at 07:55
  • @YogeshPatel - adding `estimatedHeightForHeaderInSection` (is always 0.0) keeps the table view compressed, but removes the header of the first section completely! The headers of the other sections remain. This doesn't make sense at all! – geohei May 31 '19 at 07:58
  • @AjinkyaSharma - I have no custom view for the headers. All out of the storyboard. – geohei May 31 '19 at 08:00
  • try estimateheight and header height same – Yogesh Patel May 31 '19 at 09:13
  • @YogeshPatel - I set the estimatedSectionHeaderHeight now as well to 18.0 (together w/ sectionHeaderHeight = 18.0). Nothing changed by doing that. The view remains vertically compressed exactly as without the estimatedSectionHeaderHeight. But I think PGDev (below) posted the answer. I'll dig myself through that one tomorrow. – geohei May 31 '19 at 18:20

1 Answers1

1

As per your code,

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return tableView.sectionHeaderHeight
}

You're returning sectionHeaderHeight as the header height that actually means UITableViewAutomaticDimension.

open var sectionHeaderHeight: CGFloat // default is UITableViewAutomaticDimension

As per Apple,

This nonnegative value is used only if the delegate doesn’t implement the tableView:heightForHeaderInSection: method.

The value you're getting when using print("DEBUG : ", section, tableView.sectionHeaderHeight), i.e. 18.0 is the height of the custom headerView in the .xib.

Still you're getting the proper UI because iOS automatically calculates the header height internally at runtime.

This is the reason your header shrinks when you are passing 18.0 as the header height manually.

In case you want to use separate header height for each section, you need to pass that manually in tableView(_:heightForHeaderInSection:) method, i.e.

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    switch section {
    case 0:
        return 50.0
    case 1:
        return 30.0
    default:
        return tableView.sectionHeaderHeight
    }
}

You can add more cases to the above switch statement as per your requirement. Let me know in case you still have any confusion left regarding this.

PGDev
  • 23,751
  • 6
  • 34
  • 88
  • I do not have a .xib file, since all is done via storyboard. Hence, I still don't get where `18.0` comes from. My initial intention was to hide the header of a particular section completely. I managed to do this now by the code above. I edited my initial. post. Please see above. Your code to customize sections works fine. Thanks a lot. But what is the default iOS chosen value for a header height? – geohei Jun 13 '19 at 13:16
  • 1
    By .xib I meant to say any UI in the xcode. Storyboard too comes under that. – PGDev Jun 13 '19 at 13:17