Reputation: 3456
I'd like to leverage Apple's locking section header control on my tableview (where the section header sticks to the top until pushed upward by the next section header), but I'd like to use my own view, and one that I design by xib.
Elsewhere in my app, I create views in code for the section headers and all is well, but when trying to do the same thing with a xib for a view, it gets problematic.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
ProductSectionHeader* header = self.productHeaderView;
if (!header)
{
[[NSBundle mainBundle] loadNibNamed:@"ProductSectionHeader" owner:self options:nil];
}
header.nameLabel.text = @"Some person";
header.locationLabel.text = @"Some place";
return header;
}
This shows the header view in the first section (each cell has it's own section) but then all headers disappear when the second header is prompted to show. It seems that I'm only allowed one reference to the xib or something.
So how do I reuse a xib to create multiple instances of that view in one controller, and how do I employ that into section headers?
Upvotes: 0
Views: 398
Reputation: 125007
So how do I reuse a xib to create multiple instances of that view in one controller, and how do I employ that into section headers?
A new copy of the view is created each time you load the .xib. The trick is to save the newly loaded view in a different property or variable and then clear the outlet connected to the view so that you can load another copy. So, something like this, assuming productHeaderView
is an outlet connected to the header view:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// load the view from the .xib
[[NSBundle mainBundle] loadNibNamed:@"ProductSectionHeader" owner:self options:nil];
// save it in a different variable
ProductSectionHeader* header = self.productHeaderView;
// clear the outlet for next time
self.productHeaderView = nil;
if (!header)
{
NSLog(@"There was a problem loading the view.")
}
header.nameLabel.text = @"Some person";
header.locationLabel.text = @"Some place";
return header;
}
I should also point out the relatively new UITableView method -registerNib:forHeaderFooterViewReuseIdentifier:
, which makes things even easier. You can just register a nib object with the table and let the table worry about loading the view. There's a similar method for table cells.
Upvotes: 2
Reputation: 8200
In the line where you call loadNibNamed:
, you're not doing anything with the result of that line. It returns an NSArray
containing the views from that xib file, which you're not saving. You never set header
to anything in your if statement. Assuming that xib contains only the one UIView
that you want, you would want to get the item at index 0 from that array.
Also, the fact that you're seeing a header in the first place implies to me that self.productHeaderView
is already set to something somewhere else in your code, so it never goes into your if statement in the first place. So I'm guessing you're seeing the issue you're seeing because it is trying to use the same UIView
as the header for every section, and it's causing issues because it's trying to place it in multiple spots.
If you want to fix this, make sure that you're using a unique UIView for each section, so you shouldn't be trying to store and retrieve a single UIView
in an instance variable like you are, unless you only had one section. You could maybe replace that with an NSMutableDictionary
, so that you create and store a header for each section only once, and subsequent calls to this will just retrieve it from the dictionary.
Upvotes: 2