UILabel in viewForFooterInSection text problem

13,988

Solution 1

To get the padding add the label into another view before returning that as the footer view;

- (UIView *)tableView:(UITableView *)tv viewForFooterInSection:(NSInteger)section
{
  ...
  CGRect footerFrame = [tv rectForFooterInSection:1];
  CGRect labelFrame = CGRectMake(20, 20, footerFrame.size.width - 40, footerFrame.size.height - 40);

  UIView *footer = [[UIView alloc] initWithFrame:footerFrame];
  UILabel *footerLabel = [[UILabel alloc] initWithFrame:labelFrame];

  [footer addSubview:footerLabel];
  [footerLabel release];
  ...
  return footer;
}

NB: You might want to scope *footer better to avoid a memory leak or use autorelease.

I'm not sure what the system defaults are for the label it creates to hold the text you supply as the title for footer. I guess you'll need to experiment when creating the footer label as Google hasn't thrown anything useful up.

EDIT: Rather than put all the code in the viewForFooterInSection method I use a custom UIView;

@interface CustomHeaderView : UIView {
    NSString *headerTitle;
}
@property (nonatomic, retain) NSString *headerTitle;
@end

@implementation CustomHeaderView

@synthesize headerTitle;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {

        // create frame with padding    
        CGRect labelFrame = CGRectMake(8, 8, frame.size.width - 16, frame.size.height - 16);

        UILabel *headerText = [[UILabel alloc] initWithFrame:labelFrame];
        [headerText setNumberOfLines:0];
        [headerText setFont:[UIFont boldSystemFontOfSize:14.0]];            
        [self addSubview:headerText];

        [headerText release];           
    }
    return self;
}

- (void)setHeaderTitle:(NSString *)title {

    [title retain];
    [headerTitle release];

    UILabel *label = [[self subviews] objectAtIndex:0];
    [label setText:title];
    [label sizeToFit];

    CGRect viewFrame = [self frame];
    CGRect labelFrame = [label frame];

    viewFrame.size.height = labelFrame.size.height + 16;
    [self setFrame:viewFrame];

    [self setNeedsLayout];

    headerTitle = title;
}

- (void)dealloc {
    [headerTitle release];
    [super dealloc];
}

@end

This allows me to set my title text and have the header resize for the content. I lazy load this in my view controller;

@interface MyViewController
{
    UIView *headerView;
}
- (UIView *) headerView;
@end

@implementation MyViewController

- (UIView *) headerView {

    if(headerView)
        return headerView;

    float w = [[self view] bounds].size.width;

    // height irrelevant as long as non zero custom view will resize
    CGRect headerFrame = CGRectMake(0, 0, w, 32);

    headerView = [[CustomHeaderView alloc] initWithFrame:headerFrame];

    return headerView;
}

- (UIView *) tableView:(UITableView *)tv viewForHeaderInSection:(NSInteger)sec {
    return [self headerView];
}


- (void) viewWillAppear:(BOOL)animated {
    [(CustomHeaderView *)[self headerView] setHeaderTitle:@"My Custom Header"]];
}

@end

Solution 2

Make sure u return proper height in - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section; delegate method.

Share:
13,988
daihovey
Author by

daihovey

zora, ios

Updated on June 14, 2022

Comments

  • daihovey
    daihovey almost 2 years

    I want to display two lots of text in two different footers in my table.

    The text for section 3 uses titleForFooterInSection :

    - (NSString *)tableView:(UITableView *)tv titleForFooterInSection:(NSInteger)section
    {
        if (section == 3)
            return @"SOME TEXT FOR SECTION 3";
        else
            return @"";
    }
    

    and works great and is styled correctly. I also want to add some more complicatedly formatted text (just left aligned really), so I create a label and add it to viewForFooterInSection, which works but is not padded (doesn't start at x = 20 & y = 20, starts hard up against the main windows edge) and is not styled like the other text.

    - (UIView *)tableView:(UITableView *)tv viewForFooterInSection:(NSInteger)section
    {
        if (section == 1) 
        {
            UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 20, 100, 50)] autorelease];
            label.text = @"SOME COMPLICATED TEXT FOR SECTION 1\r\n"
            "\r\n"
            "MORE TEXT HERE\r\n"
            "AND HERE.\r\n"
    
            label.backgroundColor = [UIColor clearColor];
            label.font = [UIFont systemFontOfSize:14];
            label.shadowColor = [UIColor colorWithWhite:0.8 alpha:0.8];
            label.textColor = [UIColor blueColor];
    
            label.lineBreakMode = UILineBreakModeWordWrap;
            label.textAlignment = UITextAlignmentLeft;
            label.numberOfLines = 0;
    
           [label sizeToFit];
    
        return label;       
        }
    
        else
            return nil;
    
    }
    
    -(CGFloat)tableView:(UITableView *)tv heightForFooterInSection:(NSInteger)section
    {
        if (section == 1) 
            return 180.0f;
        else if (section == 3)
            return 50.0f;
        else 
            return 0.0f;
    }
    
  • daihovey
    daihovey about 13 years
    Its getting a BAD EXE on CGRect footerFrame = [tv rectForFooterInSection:1]; - I changed it to GRect footerFrame = CGRectMake(0, 0, 320, 180); and its the same as my original example
  • Dave Anderson
    Dave Anderson about 13 years
    @daidai sorry didn't try and run that code and was trying to suggest avoiding hard coding in the width to support different screen orientations. I have a custom view class to create a padded title, see my edit.
  • daihovey
    daihovey about 13 years
    wow this is longwinded isnt it just to add a label...thanks for your reply. Ive implemented your code, but it never calls the setFooterTitle and therefore doesnt display the text...
  • daihovey
    daihovey about 13 years
    got it displaying by putting the text inside the init.
  • Dave Anderson
    Dave Anderson about 13 years
    @daidai Sure does seem excessive just for padding! I think you need to call [[self tableView] setNeedsDisplay] after you set the text in viewWillAppear. If you won't ever need to reload the view controller with a new title then init would work fine.
  • poGUIst
    poGUIst about 8 years
    It is very difficult to properly calculate footer height for all locales of UI. I want to UITableView automatic calculates proper footer height.
  • Ishank
    Ishank about 8 years
    In any case the height has to be returned from the delegate I mentioned.