24

I have a UITableView with some sections, each has its own header view. When user taps on the header view of a section, all rows of that section will collapse. What i do is, I set the number of row of that section to 0, and then call :

[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationBottom];

Everything works as expected, except one thing : the header view of the section becomes white blank. When i scroll the table, then the header becomes normal again.

So i guess there's some problem with the drawing of the table.

One funny thing is, if i use UITableViewRowAnimationFade instead, then even when i scroll the table, the header is still white blank.

When I update just ONE section there is also no problem - when I update more than one section the problem occurs.

If i use

[self.tableView reloadData]

instead, then everything works fine.

The reason i use

[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationBottom];

is because i want animation.

Wrapping with beginUpdates / endupdates does not work.

Zack Shapiro
  • 6,648
  • 17
  • 83
  • 151
Dominic Sander
  • 2,714
  • 1
  • 18
  • 29

5 Answers5

48

I realize that it's a LONG time since this question was posed but I think all of the answers given below are incorrect.

I had the same problem (with someone else's code) and was about to be fooled by this post when I realized that the code was not doing it's reuse of the table header correctly. The header disappearing was because the code was only supplying a UIView, not a UITableViewHeaderFooterView, registered correctly and set up for reuse.

Have a look at the answer here: How to use UITableViewHeaderFooterView?

My blank headers went away when I set up a reusable header.

Community
  • 1
  • 1
Darren
  • 1,417
  • 13
  • 23
  • Nice catch - seems so obvious now... :) – NSTJ Nov 08 '16 at 23:56
  • @GeneCode the answer by Raz explains the re-use process fairly well. – Darren Jan 23 '17 at 22:00
  • 1
    @Darren Thanks for this answer. I added some Swift notes below – Zack Shapiro Apr 07 '17 at 21:00
  • This works for me in iOS 12! I had a custom `UITableViewCell` with Xib-File as Header. Funny thing is that I left the Xib as it was and just made the custom class subclass of `UITableViewHeaderFooterView` and changed the register and dequeuing functions for the table view and it was working :) – heyfrank Oct 10 '18 at 12:06
  • Good solution! You save my day. Thanks – Yano Feb 13 '20 at 14:29
3

In Swift:

You need to create a class that's a subclass of UITableViewHeaderFooterView and register it to the table view. Then in viewForHeaderInSection, you do let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as! YourHeaderView, similar to what you do for UITableViewCells. Then return that header.

The deceptive thing is the function calls for a return of UIView? when it really needs a dequeuedReusableHeaderFooterView or reloadData will cause it to disappear

Zack Shapiro
  • 6,648
  • 17
  • 83
  • 151
1

I found a work-around - not very elegant, but it works. Instead of providing a NSIndexSet with more than one section, I call the reloadSections within a for-loop with only one section in each call.

looks like:

    for (Element *eleSection in self.gruppenKoepfe) {
        if ( eleSection.type.integerValue == qmObjectTypeFormularSpalte || eleSection.type.integerValue == qmObjectTypeFormularZeile ) {
            [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:nCount] withRowAnimation:UITableViewRowAnimationFade];
        }
        nCount ++;
    }     
Dominic Sander
  • 2,714
  • 1
  • 18
  • 29
0

I was having a similar problem, except I was trying to delete/insert sections, and I found that keeping a strong property pointing to the entire header view (i.e. not just a subview) stopped it disappearing during section updates.

e.g. Property and instantiation

@property (nonatomic, strong) UIView *headerView;

-(UIView *)headerView {
  if ( !_headerView ) {
    _headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.view.bounds.size.width, 300)];
    // add additional view setup, including subviews
  }
  return _headerView;
}

And in tableView:(UITableView *)viewForHeaderInSection:(NSInteger)section:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if ( section == theCorrectSection ) {
        return self.headerView;
    }
    return nil;
}
0

I had the same issue and it was none of the above. My problem was that i was hidding the first header and for some reason after more then 10 reloads the header at index 2 was set hidden. When i set headerView.hidden = false it was ok.