-3

I've done a lot of reading already on this, but it's seems like there's no simple solution.

I'm trying to make an app that loads an NSArray of NSString comments to display in a UITableView. The comments all vary in size.

How can I get the cell to adjust its size to show the entire content of each comments?

I'm trying to find a simple solution without resorting to using magic CFloat numbers.

Is there a method in apple's API that allows me to calculate the needed height of the cell.detailTextLabel given an NSString comment and fixed width?

I think if I can calculate this height, all that's need is to set the height of the cell and the height of the row.

Not really sure what order to do this in since I've read the cell hasn't been created yet when heightForRow:AtIndexPath: gets called.

Jakub
  • 13,712
  • 17
  • 82
  • 139
  • possible duplicate of [iOS calculate text height in tableView cell](http://stackoverflow.com/questions/14841193/ios-calculate-text-height-in-tableview-cell) – Sergey Kalinichenko Jan 19 '14 at 13:05
  • possible duplicate [Dynamic Height of UITableViewCell](http://stackoverflow.com/questions/10744277/dynamic-height-of-uitableviewcell?rq=1) – voromax Jan 19 '14 at 13:36

4 Answers4

2

Calculate the height of the text in tableView:heightForRowAtIndexPath:

You need to use boundingRectWithSize:options:context: on iOS 7+ and sizeWithFont:forWidth:lineBreakMode: on iOS 6 and below. See the apple documentation for more information.

UIFont   *font    = [UIFont oka_commentLabelFont];
NSString *text    = [self commentForIndexPath:indexPath];
CGFloat cellWidth = 300.f;

CGSize boundingSize = CGSizeMake(widthForCell, CGFLOAT_MAX);
CGSize size;

if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
  size = [text boundingRectWithSize:boundingSize
                            options:NSStringDrawingUsesLineFragmentOrigin
                         attributes:@{ NSFontAttributeName : font }
                            context:nil].size;
} else {
  size = [text sizeWithFont:font
          constrainedToSize:boundingSize
              lineBreakMode:NSLineBreakModeWordWrap];
}

return size.height;

You need to set the font to the same font you want to use on the cell. If you put this in a performUpdates block on the tableView then you will get a nice expanding animation.

Oliver Atkinson
  • 7,970
  • 32
  • 43
  • Doesn't seem to be working. My text still end in ellipsis but the cell is now huge. – user3142893 Jan 19 '14 at 13:38
  • 2
    Have you set the auto-resizing mask on the label? maker sure it has resizable height. If you use IB its easy, see the image: http://www.techotopia.com/images/2/27/Iphone_view_autosize_height_width.jpg You will want it everything checked - so its red. – Oliver Atkinson Jan 19 '14 at 13:51
  • Do you mean auto layout 4 sides constraint on the label in storyboard? I tried doing that but it won't let me. – user3142893 Jan 19 '14 at 13:59
  • 1
    Turn auto-layout off for the cell nib, just use auto-resizing masks it will be good enough for your needs. – Oliver Atkinson Jan 19 '14 at 14:36
  • I tried this in -cellForRowAtIndexPath, [cell setAutoresizesSubviews:YES]; cell.autoresizingMask= UIViewAutoresizingFlexibleHeight; It doesn't seem to work. – user3142893 Jan 19 '14 at 14:45
  • Using your code seems to compress the height of the cell for some reason. I logged them and they all came out to 22.0. The width seems to be changing. I also logged my comments and they all came out normally. – user3142893 Jan 19 '14 at 14:52
  • Hey, I've seemed to fix it, but in some cells, there's still too much free space on top and at the botton. – user3142893 Jan 19 '14 at 15:05
  • 1
    Are you using the correct width input? e.g. if your cell is 200px wide, make sure it reflects whats in the height for row. Another thing to check is to make sure the font is the same! – Oliver Atkinson Jan 19 '14 at 17:11
  • I tried playing around with the font size. Some cell is a little bit too tight and some have too much room. Not sure what to do, but instead of using subtitle cell, I chose the custom option and added my own labels with constraint. – user3142893 Jan 19 '14 at 17:43
  • 1
    Place the label on a UIView which is 10px in from the left and 10px in from the right, that way it wont hug the edges of the view. Move this to chat if you want to discuss further – Oliver Atkinson Jan 19 '14 at 17:45
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/45584/discussion-between-user3142893-and-oliver-atkinson) – user3142893 Jan 19 '14 at 18:10
1

Don't set the height of the cell, set the height of the row and the table view will do the rest.

To calculate the height of the text, ask a label with textRectForBounds:limitedToNumberOfLines:, or ask the string with one of the many methods like sizeWithFont:constrainedToSize:lineBreakMode:.

You may need to deal with padding around the label when compared to the size of the cell.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • So once I set my comments NSString to the `cell.detailTextLabel`, I use `textRectForBounds:limitedToNumberOfLines:` ? But the thing is, I'm not assigning my comments until cellForRowAtIndexPath, so my cell.detailTextLabel is still nil when heightForRowAtIndexPath gets called. – user3142893 Jan 19 '14 at 13:13
  • No, you should have an array of strings or something like that. Use the string from there in `tableView:heightForRowAtIndexPath:` – Wain Jan 19 '14 at 13:17
0

yes we can calculate the height of UILabel depending on the Font and line break mode.

UIFont * font = [UIFont systemFontOfSize:12.0];
CGSize newSize = [text sizeWithAttributes:@{NSFontAttributeName:font}];// You can add other attributes in dictionary to like line break mode.

Here you got new size for the text which will be in UILabel, now in hegihtForCellAtIndexPath method you can change the size of UITableViewCell. newSize.height is height you need for label, now you can add some value to it for offsets and return it.

Adnan Aftab
  • 14,377
  • 4
  • 45
  • 54
  • sizeWithFont is deprecated though. Is 296 the maximum with of a cell? What if I'm trying to make my code more usable to adjust to the ipad and other devices? I'm not sure where I would put your code in, heightForRowAtIndexPath? People keep saying that the cell and its textlabel is still nil when heightForRowAtIndexPath gets called. – user3142893 Jan 19 '14 at 13:20
  • In your new code, when are you using maximumLabelSize variable? Do you just throw it in the dictionary that passes to sizeWithAttribute? – user3142893 Jan 19 '14 at 13:55
  • This is not required now, I am removing this. – Adnan Aftab Jan 19 '14 at 14:49
  • You can use systemfont with size 12 if you not have custom cell – Adnan Aftab Jan 19 '14 at 14:57
-1

Use

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
   return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
R00We
  • 1,931
  • 18
  • 21
  • How is this different from omitting the implementation of `tableView:heightForRowAtIndexPath:`? – Sergey Kalinichenko Jan 19 '14 at 13:06
  • Are you suggesting that I use this if I decide to subclass UITableView or UITableViewCell? Because I'm trying to find a simple solution without resorting to subclassing. I don't want to do a lot of coding to find out Apple has some simple method to solve this. – user3142893 Jan 19 '14 at 13:08