10

Current I am creating a prototype cell in storyboard and using this cell as a section header. Inside tableView:viewForHeaderInSection: method, I am dequeuing the cell and returning it.

My section header cell has a UITextField and a UIButton in it. When I tap on text field keyboard appears but as soon as focus is moved away from text field whole section header disappears. This happens when I return the cell directly as section header view, but if I return a newly allocated UIView as section header view onto which cell is added as subview then everything works fine besides autoresizing masks.

Why header is disappearing?

I am not sure what could be the best thing todo here.

-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    static NSString *CellIdentifier = @"SectionHeader"; 

SettingsTableViewCell *sectionHeaderCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    //return sectionHeaderCell; // returning cell directly, section header disappears when focus is moved away from text field.
UIView * headerView = [[UIView alloc] initWithFrame:sectionHeaderCell.frame];
[headerView addSubView:sectionHeaderCell];
return sectionHeaderCell;//header view never disappears, but auto resizing masks do not work. Need to know how to set autoresizing masks to headerView so that it resizes correctly.

}  
dev gr
  • 2,409
  • 1
  • 21
  • 33
  • 1
    The best way is to make it in a xib file, not a storyboard. – rdelmar Dec 20 '14 at 06:22
  • 1
    @rdelmar tableview is in storyboard and i am creating prototype cell in it which serves as a section header. I am not interested in creating a separte xib file just for section header view in today's storyboard world. – dev gr Dec 20 '14 at 06:27
  • Possible duplicate of [How to Implement Custom Table View Section Headers and Footers with Storyboard](http://stackoverflow.com/questions/9219234/how-to-implement-custom-table-view-section-headers-and-footers-with-storyboard) – Hemang Feb 01 '16 at 05:46

4 Answers4

23

Prototype cell table views only allow you to design cells in the storyboard editor, not section headers and footers. Your attempt to use a UITableViewCell as the section header is a clever hack, but it's just not supported by the classes involved—UITableViewCell is not designed to be used for anything other than a table view cell. It could do a lot worse than the view disappearing or not being laid out correctly; UIKit would be well within its rights to fail an assertion, delete all the app's data, revoke your developer certificate, or set your house on fire.

If you want your code to function properly, your choices are to either create your section headers in code or to put them in a separate XIB file. I know that's not what you want to do, but those are the options you have.

Becca Royal-Gordon
  • 17,541
  • 7
  • 56
  • 91
  • Okay, I created an XIB file which has header views. I assigned custom class to those views and I am returning those view as header views from inside viewForHeaderInSection: method. Now those header views are getting deallocated automatically. What should I do? I could see them but as soon as I send any message to them I get 'unrecognized selector sent' error. – dev gr Dec 22 '14 at 09:10
  • @devgr You need to edit your question to include the code you're now using, so we can see what you're doing. – rdelmar Dec 23 '14 at 05:44
  • One big gripe is what if you need to create a segue on the section header (such as tapping it showing another view controller). Then in the storyboard, the two view controllers doesn't get linked since you need a source "thing" to create segues from. – adib May 08 '15 at 13:48
  • 3
    I've tried [Michael Voznesensky's approach](https://medium.com/@MichaelVoznesensky/fully-interactive-ios-section-headers-in-swift-47a5d8c30386) and it seems to work. – adib May 08 '15 at 14:25
9

I had the same issue and the fix was to return the cell's contentView like:

-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
static NSString *CellIdentifier = @"SectionHeader"; 

   SettingsTableViewCell *sectionHeaderCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

   sectionHeaderCell.myPrettyLabel.text = @"Greetings";
   sectionHeaderCell.contentView.backgroundColor = [UIColor whiteColor]; // don't leave this transparent

   return sectionHeaderCell.contentView;
}  

And you get the same autolayouted results as before, but without the disappearing.

Laszlo
  • 2,803
  • 2
  • 28
  • 33
2

I am sure you can use UITableViewCell as a section header, because UITableViewCell is subclass of UIView, so according to LSP

“objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.”

Sergey Demchenko
  • 2,924
  • 1
  • 24
  • 26
  • 5
    But section headers _should_ be an instance of `UITableViewHeaderFooterView` – adib May 08 '15 at 13:45
  • @adib, It is not required. Take a look on - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section method. – Sergey Demchenko May 08 '15 at 17:16
  • but you need to [wrap it in another `UIView`](http://stackoverflow.com/a/22752404/199360) otherwise the table view may mess around with it. – adib May 17 '15 at 04:30
  • they will trigger `didSelectedRowAtIndexPath` though – yershuachu Jan 26 '16 at 10:32
2

In iOS 8, it's simple really. Just design your header the same way you design your cell. Everything is the same, you can put custom class and don't forget to add reuse identifier.

When it comes to use it in the code, just return that cell in tableView:viewForHeaderInSection method.

Don't forget to implement tableView:heightForHeaderInSection if you want to use fix height or tableView:estimatedHeightForHeaderInSection if the height depends on the cell intrinsic size.

  • Thank you very much! I actually complicated the issue cause the method expects an UIView instead of cell, then after looking at your answer only I check the UITableViewCell class and tested it out. Worked from my side, SERIOUSLY thank you – Happiehappie Jan 07 '16 at 10:51
  • Have you even read the question? He does the same thing, and if you do this, then your header-cell will disappear because the tableView thinks its not in use, so its reusing it. – Laszlo Feb 03 '16 at 15:24