Fix the Table header gap in iOS 15

Galvin Li
3 min readSep 17, 2021

Xcode 13RC is release. Then I download it and make a test for my application, a gap appear in my Home page.

But it use to be look like this

It must be a ‘feature’ in iOS15, so I do some search and found most people told you to do this

if #available(iOS 15, *) {
tableView.sectionHeaderTopPadding = 0
}

But nothing work. And I also found someone has the same issue with me and also post a Demo project(Github link) to reproduce the issue.

But no one find a way to fix that. So it’s my turn.

If you just need the answer, just scroll to the bottom and you will see the code.

In the demo project, Kjek help to reproduce an issue table and also a non issue table with the same structure.

So now we know:

Issue: async fetch data from network
No issue: sync load local data

Network should not cause the issue, and it delay my to reproduce the issue. So I try to just async load local data and success reproduce the issue.

So now we know:

Issue: async load local data
No issue: sync load local data

Looks like async make the issue, but we can’t make all request sync, so we need to make more try. So what about we sync load some fake data then async load the real data? I make a try and find out that also have no issue.

But when the async data not loaded then user will see the fake date that we load. So what about sync load empty data? I make a try and find out the issue still happen.

So now we know:

Issue: sync load empty data, then async load local data
No issue: sync load local data, then async load local data

So I start to think, what’s the different between empty data and local data? The data make the cell appear, and also the header view. I think the gap is more related to the header than the cell because it just show up at the top. So I make a assume:

sync load empty data => no header 
sync load local data => header exist

So I add a `tableHeaderView` in `viewDidLoad`, then… issue gone. 🎉

Let’s sum up. This issue cause by the table header view when the view appear. If the header exist, then the issue gone. If the header no exist, then the gap appear. So to fix that, just add a `tableHeaderView` on `viewDidLoad`. And remember tomake sure the header with a non zero height.

swift version:

tableView.tableHeaderView = .init(frame: .init(x: 0, y: 0, width: 0, height: CGFloat.leastNonzeroMagnitude))

objective-c version:

self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];

But what if we have many many table using in my project? Do I need to edit all of them?

Sure not! Because iOS have a thing name `appearance`, just add the below code after your app launch like `didFinishLaunchingWithOptions`, it will fix all your tableviews.

swift version:

UITableView.appearance().tableHeaderView = .init(frame: .init(x: 0, y: 0, width: 0, height: CGFloat.leastNonzeroMagnitude))

objective-c version:

[UITableView appearance].tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];

Hope this article help you solve the issue and more other issues. If this article help you, tap the clap👏 will help more people find this. And you also can follow my Medium and Twitter.

--

--

Galvin Li

A Tiny iOS developer who love to solve problems and make things better.