geohei
geohei

Reputation: 802

Section header height differs when set manually

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).

Upvotes: 0

Views: 1126

Answers (1)

PGDev
PGDev

Reputation: 24341

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.

Upvotes: 1

Related Questions