I have a UITableView
with 2 sections. Each with it's own headerView
.
I have created a custom headerView
via the -viewForHeaderInSection:
method.
Later, I plan to modify it a bit so I need to use the viewForHeader
method but I am unable to access the headerView
and it's subViews
.
As a simple example, I'm trying to NSLog
the viewForHeader
object in the -didSelectRowAtIndexPath:
but I get a (null)
result.
Sample Code:
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 75;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *myHeader = [[UIView alloc] init];
switch (section) {
case 0:
[myHeader setBackgroundColor:[UIColor greenColor]];
break;
case 1:
[myHeader setBackgroundColor:[UIColor redColor]];
break;
default:
break;
}
UILabel *myLabel = [[UILabel alloc] init];
[myLabel setFrame:CGRectMake(10, 0, 100, 30)];
[myLabel setTag:101];
[myLabel setBackgroundColor:[UIColor clearColor]];
[myLabel setText:[NSString stringWithFormat:@"Section: %d",section]];
[myHeader addSubview:myLabel];
return myHeader;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewHeaderFooterView *testView = [self.tableView headerViewForSection:indexPath.section];
NSLog(@"%@",testView); //displays (null)
}
Do I need to create the custom UIView
xib as the headerView
? (because as per a similar question and as per the docs")
To make the table view aware of your header or footer view, you need to register it.
You do this using the registerNib:forCellReuseIdentifier: or
registerClass:forCellReuseIdentifier: method of UITableView.
Ok, after some trial and error, I finally solved my own dilemma.
I did the headerView
just as I would do a cell.
For a cell we would take UITableViewCell
and use dequeueReusableCellWithIdentifier
while...
For a Header/Footer, we will take UITableViewHeaderFooterView
and use the dequeueReusableHeaderFooterViewWithIdentifier
method.
The rest is pretty much the same concept as a cell.
UITableViewHeaderFooterView
won't work with iOS5 and below)Creating and using the default UITableViewHeaderFooterView
within -viewForHeaderInSection:
method:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
static NSString *HeaderIdentifier = @"header";
UITableViewHeaderFooterView *myHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:HeaderIdentifier];
if(!myHeader) {
myHeader = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:HeaderIdentifier];
}
UIButton *btnUp = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnUp setTag:101];
[btnUp setTitle:@"-" forState:UIControlStateNormal];
[btnUp setFrame:CGRectMake(tableView.frame.size.width - 35, 5, 30, 30)];
[myHeader addSubview:btnUp];
[myHeader.textLabel setText:[NSString stringWithFormat:@"Section: %d",section]];
[myHeader setFrame:CGRectMake(0, 0, tableView.frame.size.width, 50)];
return myHeader;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewHeaderFooterView *theHeaderView = [tableView headerViewForSection:indexPath.section];
NSLog(@"%@",theHeaderView); // -- great! ... not (null) anymore
UIButton *theButton = (UIButton *)[theHeaderView viewWithTag:101];
[theButton setTitle:@"+" forState:UIControlStateNormal];
}
Using a custom UITableViewHeaderFooterView
subclass:
UITableViewHeaderFooterView
subclass and named it CustomHeaderView
CustomHeaderView
@property (strong, nonatomic) IBOutlet UILabel *lblSomething;
@property (strong, nonatomic) IBOutlet UIButton *btnSomething;
Modified the -viewForHeaderInSection:
& -didSelectRowAtIndexPath:
as:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
static NSString *HeaderIdentifier = @"header";
CustomHeaderView *myHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:HeaderIdentifier];
if(!myHeader) {
// [tableView registerClass:[CustomHeaderView class] forHeaderFooterViewReuseIdentifier:HeaderIdentifier];
myHeader = [[[NSBundle mainBundle] loadNibNamed:@"CustomHeaderView"
owner:self
options:nil] objectAtIndex:0];
}
[myHeader.btnSomething setTitle:@"-" forState:UIControlStateNormal];
[myHeader.lblSomething setText:[NSString stringWithFormat:@"Section: %d",section]];
return myHeader;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomHeaderView *theHeaderView = (CustomHeaderView*)[tableView headerViewForSection:indexPath.section];
NSLog(@"%@",theHeaderView);
[theHeaderView.lblSomething setAlpha:theHeaderView.lblSomething.alpha-0.1];
[theHeaderView.btnSomething setTitle:@"+" forState:UIControlStateNormal];
}
PS: The issue with UITableViewHeaderFooterView
is that it is iOS6+ only and if, for any reason, your header is/must be a UIView
, then see the next method
Using a simple UIView
:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *vwHeader = [[UIView alloc] init];
[vwHeader setTag:200 + section]; //[1] first method
switch (section) {
case 0:
[vwHeader setBackgroundColor:[UIColor greenColor]];
break;
case 1:
[vwHeader setBackgroundColor:[UIColor redColor]];
break;
default:
break;
}
UILabel *lblTitle = [[UILabel alloc] init];
[lblTitle setFrame:CGRectMake(10, 0, 100, 30)];
[lblTitle setTag:100 + section]; //[2] alternative method
[lblTitle setBackgroundColor:[UIColor clearColor]];
[lblTitle setText:[NSString stringWithFormat:@"Section: %d",section]];
[vwHeader addSubview:lblTitle];
return vwHeader;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIView *vwTest = [self.tableView viewWithTag:200 + indexPath.section]; //[1]
NSLog(@"[1] : %@",vwTest);
//or
UILabel *lblTest = (UILabel *)[self.tableView viewWithTag:100 + indexPath.section]; //[2]
NSLog(@"%@",lblTest.text);
UIView *vwTestForSuperview = lblTest.superview;
NSLog(@"[2] : %@",vwTestForSuperview);
}
PS: I know this code doesn't serve any great purpose but this is just an example for others.
I think your problem can be solved easily enough:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UITableViewHeaderFooterView *myHeader = [[UITableViewHeaderFooterView alloc] init];
switch (section) {
case 0:
[myHeader setBackgroundColor:[UIColor greenColor]];
break;
case 1:
[myHeader setBackgroundColor:[UIColor redColor]];
break;
default:
break;
}
UILabel *myLabel = [[UILabel alloc] init];
[myLabel setFrame:CGRectMake(10, 0, 100, 30)];
[myLabel setTag:101];
[myLabel setBackgroundColor:[UIColor clearColor]];
[myLabel setText:[NSString stringWithFormat:@"Section: %d",section]];
[myHeader addSubview:myLabel];
return myHeader;
}
Basically, you need to use UITableViewHeaderFooterView class to return from viewForHeaderInSection callback. After that, calling headerViewForSection on your table view will be returning you valid instances of objects instead of nil.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With