Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic heightForHeaderInSection

How can I modify the height of a header section accordantly to the view I'm adding it?
heightForHeaderInSection is called before viewForHeaderInSection and I don't know the view size until I create it.

like image 427
pasine Avatar asked Mar 05 '12 09:03

pasine


2 Answers

You can follow this:

  1. Create a property for headerView (NSArray if multiple header views).
  2. Create the view in "heightForHeaderInSection" itself.
  3. Assign your view to property.
  4. return the height of your view in "heightForHeaderInSection".
  5. In "viewForHeaderInSection" return this property.
like image 69
Abhay Singh Avatar answered Jan 04 '23 00:01

Abhay Singh


Yeah, it seems strange/redundant that you have to create both the view and then also determine the size of that view as a completely separate event, but you can minimize the silliness by moving some of that shared logic into some shared method. E.g., you probably have to figure out the size of the view at some point during it's creation, so move that logic to some shared method.

For example, I have logic that I use for determining the size of the UILabel I'm putting in my header based upon the size of the text. So I pulled that out of my viewForHeaderInSection and moved it into my own method, sizeForHeaderLabelInSection, which I use to determine the size of my label control):

- (CGSize)tableView:(UITableView *)tableView sizeForHeaderLabelInSection:(NSInteger)section
{
    NSString *text = [self tableView:tableView titleForHeaderInSection:section];

    CGSize constraint = CGSizeMake(self.view.frame.size.width - kSectionTitleLeftMargin - kSectionTitleRightMargin, kMaxSectionTitleHeight);
    return [text sizeWithFont:[self fontForSectionHeader] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
}

Then, I modified the standard heightForHeaderInSection to use that method, adding, of course, my top and bottom margin around my UILabel:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{    
    return [self tableView:tableView sizeForHeaderLabelInSection:section].height + kSectionTitleTopMargin + kSectionTitleBottomMargin;
}

And then I modified the standard viewForHeaderInSection to also use this sizeForHeaderLabelInSection, too:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    CGSize size = [self tableView:tableView sizeForHeaderLabelInSection:section];

    UIView* headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, size.width + kSectionTitleLeftMargin + kSectionTitleRightMargin, size.height + kSectionTitleTopMargin + kSectionTitleBottomMargin)];
    //headerView.contentMode = UIViewContentModeScaleToFill;

    // Add the label
    UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(kSectionTitleLeftMargin, 
                                                                     kSectionTitleTopMargin, 
                                                                     size.width, 
                                                                     size.height)];
    // put stuff to set up my headerLabel here...

    [headerView addSubview:headerLabel];

    // Return the headerView
    return headerView;
}

Clearly, how you do this is completely up to you and what you're trying to achieve. But I think you'll have success if you shift your mindset from "how do I figure out the size of that view I created in viewForHeaderInSection" to "how can I move the the code that I used for determining the size in viewForHeaderInSection into some common method that my heightForSectionInHeader can use, too.

like image 21
Rob Avatar answered Jan 03 '23 23:01

Rob