2

If I'm making a custom UITableViewCell and I need it to have a variable height depending on the length of the input (for instance, for a Twitter reader or something), how can I make this work?

I've found lots of other examples here that can set it for a the standard, non-custom cell, but my cell's main text label is smaller, etc., so when I try to use any of those methods on my cell, they give a variety of weird results (text overlapping the bottom of the cell, etc.)

Is there a standardized way of designing the cell (for example, how tall should I make it in Interface Builder?), and let's say my label was half the width of that cell.. how would I go about calculating the height the cell would need to be to display the string loaded into that label? Here's a method that I found here which works fine on the normal cell, but screws up custom ones with weird heights, overlapping text, etc: (I have absolutely NO idea what the 300 / 200000 do here, if anyone could explain that I'd be grateful, too!)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGSize  textSize = {300.f, 200000.0f};
    CGSize  size = [[_quoteStringsFromPlist objectAtIndex: indexPath.row] sizeWithFont: [UIFont systemFontOfSize:12.0f] constrainedToSize: textSize lineBreakMode: NSLineBreakByWordWrapping];
    size.height += 5.0f;
    float result = MAX(size.height, 32.0f);
    return result;
}
Luke
  • 9,512
  • 15
  • 82
  • 146
  • You can do all this in interface builder (if you are okey with that). In IB select the tableview and change the row height. Then select the cell and choose custom cell height and enter the same number. Hope it helps! – Groot Feb 15 '13 at 12:36
  • This hasn't worked, I'm afraid. The cells appear to be at different heights, but the short ones have loads of space above/below them, and the longer ones are being cut off. I set the row height to 90 in both places. – Luke Feb 15 '13 at 12:43

2 Answers2

0

First, head over to your xib file and see how large are the top/bottom margins of your text area, and how wide it is.

After that, you need to calculate the height needed for it with the width you have available, and then add that value to the top/bottom margins your text area already has.

The result should look correctly regardless of the size of each cell in IB or the text you are trying to put in them.

EDIT

Imagine your cell size is {700, 300} in your IB, and your text area is located on {{100, 100}, {300,100}}, your text area has a 100px margin top and 100px margin bot, and it's width is 300.

When you calculate the height you require for your text, you calculate it with an available 300 width. It will return a size, something like {300, 250}. That 250 is the height required by your text, but your cell has other stuff in it and you need to add those top and bot margins to that, so the result is 450.

Remember to set an autoresizing mask or autolayout so that your text area stretches vertically and the margins are fixed (UIViewAutoresizingFlexibleHeight)

Ismael
  • 3,927
  • 3
  • 15
  • 23
  • Could you provide an example? I'm not really following this at all. My text area in the storyboard is 159 wide, and 74 high (at X 234 and Y 45, if that matters). I'm not sure what you mean by margins. – Luke Feb 15 '13 at 12:40
  • whats the name of the property for the text margins? – AlexWien Feb 15 '13 at 12:46
  • I don't know what autoresizing masks are, at all. I'm sorry to be a problem here, but I still don't really have a clue what you mean by this answer. – Luke Feb 15 '13 at 13:08
  • So the problem I'm having is that the cells are resizing, but the larger ones have larger margins, and the smaller ones have almost no margins. – Luke Feb 15 '13 at 21:53
0

Something like this should work.

CGRect labelFrame = // enter default frame of the label here
UIFont *labelFont = // enter label font here
CGFloat labelBottomMargin = // enter the space between the bottom of the label and the bottom of the cell here

CGSize  size = [labelString sizeWithFont:labelFont constrainedToSize:CGSizeMake(labelFrame.size.width, MAX_FLOAT)];
size.height += labeFrame.origin.y;
size.height += labelBottomMargin;
size.height = MAX(size.height, 32.0f);
return size.height;
user941868
  • 26
  • 2
  • That makes them all WAY too tall, like more than twice the height they need to be. – Luke Feb 15 '13 at 13:05
  • Also, where's the 32.0f come from? – Luke Feb 18 '13 at 17:53
  • It comes from you. From your original code I assumed that 32.0f was the minimum height you wanted for your cell. The code I provided should work if you entered the correct values for labelFrame, labelBottomMargin, and labelFont. – user941868 Feb 20 '13 at 13:11