0

I have a nib with a table cell, and within that table cell I have a UILabel. I want to make that label sizeToFit which means I have to do:

- (void)viewDidLoad {
    [self sizeToFit];
}

However my label doesn't have any code, just an outlet to a variable in my controller, so there's nowhere I can put that code to effect the label.

I attempted making a sub class of UILabel (fitUILabel : UILabel) and then I clicked on the label in the nib and set its class to fitUILabel, however it does not seem to run.

In my controller right before the return statement in cellForRowAtIndexPath I tried putting

 [cell.myLabelOutletVariable sizeToFit]

And this seems to work, however it only works on the recycled rows and not the labels contained in the initial cells of my table. This also seems to cause my text to flow right out of the cells and overlap onto others, however it does align it to the top which is what I wanted.

David Zorychta
  • 13,039
  • 6
  • 45
  • 81

3 Answers3

1

I assume you mean that your nib contains a UITableViewCell as a top-level object, and the table view cell has a UILabel subview.

The viewDidLoad method is defined on UIViewController, and UITableViewCell doesn't inherit from UIViewController.

UITableViewCell is a subclass of UIView. The proper place for a view to adjust the frames of its subviews is in its layoutSubviews method. You need to make a subclass of UITableViewCell, and set that as the custom class of the cell in your nib. Then, in your subclass, define this method:

- (void)layoutSubviews {
    [self.label sizeToFit];
}

In your table view data source's tableView:cellForRowAtIndexPath: method, you may want to send setNeedsLayout to the cell after setting the text of the label. This will ensure that the cell receives layoutSubviews again, if it's being reused.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCell *cell = ...;

    cell.customLabel.text = [self labelTextForIndexPath:indexPath];
    [cell setNeedsLayout];
    return cell;
}

Alternatively, you could make a UILabel subclass, like this:

@implementation MyLabel

- (void)layoutSubviews {
    [self sizeToFit];
}

- (void)setText:(NSString *)text {
    [super setText:text];
    [self setNeedsLayout];
}

@end

and then set MyLabel as the custom class of the label in your nib. But having a view set its own frame in layoutSubviews seems a little fishy to me, so I usually avoid it.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • That works, however if I want to do something else to my label in layoutSubviews such as moving the position of my label: myLabel.frame = CGRectMake(...) then it works but only on the recycled cells. – David Zorychta Apr 27 '13 at 21:43
  • Infact, if I do myLabel.numberOfLines = 0; then I have to press on each cell to make the attribute apply. Could this have anything to do with my heightForRowAtIndexPath method calculating cell heights dynamically? – David Zorychta Apr 27 '13 at 22:12
  • Ah, I see what (I think) is happening. layoutSubviews runs fine but then my heightForRowAtIndexPath runs after it and resizes my cells, but following this it doesn't make a call back to layoutSubviews. So I either need a way to make it call layoutSubviews again or I somehow need to make my label in the nib designer be a percentage height and not in points. I'll keep digging here but if you know what's up I sure would appreciate it! – David Zorychta Apr 27 '13 at 22:23
0

You should put your code for size the Label in Table view's Delegate Method CellForRowAtIndexPath and not in viewDidLoad. If your Label is in Table View Cell.

Sam
  • 431
  • 7
  • 23
0

You may rewrite the -(void) awakeFromNib method for initializing the Label.