Friday, June 7, 2013

UITableView registerClass forHeaderFooterViewReuseIdentifier example in Objective C (iOS).


UITableView registerClass forHeaderFooterViewReuseIdentifier

Registers a class for use in creating new table header or footer views.

- (void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier

Parameters of [UITableView registerClass forHeaderFooterViewReuseIdentifier]
aClass
The class of a header or footer view that you want to use in the table.
identifier
The reuse identifier for the header or footer view. This parameter must not be nil and must not be an empty string.

Discussion of [UITableView registerClass forHeaderFooterViewReuseIdentifier]
Prior to dequeueing any header or footer views, call this method or the registerNib:forHeaderFooterViewReuseIdentifier: method to tell the table view how to create new instances of your views. If a view of the specified type is not currently in a reuse queue, the table view uses the provided information to create a one automatically.

If you previously registered a class or nib file with the same reuse identifier, the class you specify in the cellClass parameter replaces the old entry. You may specify nil for cellClass if you want to unregister the class from the specified reuse identifier.

UITableView registerClass forHeaderFooterViewReuseIdentifier example.
If you wanted to have a reusable UITableViewHeaderFooterView without subclassing then you simply change your viewDidLoad to this:

// Register the class for a header view reuse.
[_buttomTableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"TableViewSectionHeaderViewIdentifier"];
and then your delegate method to this:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 40.0;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    static NSString *headerReuseIdentifier = @"TableViewSectionHeaderViewIdentifier";

   // Reuse the instance that was created in viewDidLoad, or make a new one if not enough.
    UITableViewHeaderFooterView *sectionHeaderView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier];
    // Add any optional custom views of your own
    UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 50.0, 30.0)];
    [customView setBackgroundColor:[UIColor blueColor]];

    [sectionHeaderView.contentView addSubview:customView];
    sectionHeaderView.textLabel.text = @"Non subclassed header";

    return sectionHeaderView;

}

Example of [UITableView registerClass forHeaderFooterViewReuseIdentifier].
you just need to use the same identifier when you register, and when you dequeue the header view. In the viewDidLoad method, I registered the view like this:

[self.tableView registerNib:[UINib nibWithNibName:@"Header1" bundle:nil] forHeaderFooterViewReuseIdentifier:@"header1"];
Then, in the delegate methods:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *headerView = [self.tableView dequeueReusableHeaderFooterViewWithIdentifier:@"header1"];
    return headerView;
}

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 100;
}

UITableView registerClass forHeaderFooterViewReuseIdentifier example.
First step: you're telling the table view what class to use for the section header view, by registering your custom subclass of UITableViewHeaderFooterView (I assume your M3CHeaderFooter is a subclass of UITableViewHeaderFooterView).

Second step: Tell the table view what view to use (AND reuse) for a header section by implementing the tableView delegate method

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
So in your viewDidLoad you'd implement something like this:

    // ****** Do Step One ******
    [_tableView registerClass:[M3CHeaderFooter class] forHeaderFooterViewReuseIdentifier:@"TableViewSectionHeaderViewIdentifier"];
Then you'd implement the table View delegate method in the class where you're creating and displaying your table view:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 40.0;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    static NSString *headerReuseIdentifier = @"TableViewSectionHeaderViewIdentifier";

    // ****** Do Step Two *********
    M3CHeaderFooter *sectionHeaderView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier];
   // Display specific header title
   sectionHeaderView.textLabel.text = @"specific title";  

    return sectionHeaderView;   
}
Now mind you that you do not need to subclass UITableViewHeaderFooterView in order to use it. Before iOS 6, if you wanted to have a header view for a section, you'd implement the above tableView delegate method and tell the table view what view to use for each section. So each section had a different instance of a UIView which you provided. This means that if your tableView had 100 sections, and inside the delegate method you created a new instance of a UIView, then you would have given the tableView 100 UIViews for the 100 section headers that were displayed.

End of UITableView registerClass forHeaderFooterViewReuseIdentifier example article.