Reputation: 7959
In my case, how would I resize a UITableViewCell
to accomodate the height of a UITextView
that it contains?
I'm currently trying to achieve this using the following code:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// init the font that we use
UIFont *font = [UIFont fontWithName:@"SourceSansPro-Regular" size:16];
if (indexPath.section == 0) {
// get the text size of the thread
CGSize textSize = [_thread.text sizeWithFont:font constrainedToSize:CGSizeMake(280, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
return textSize.height + 20;
}
// default
return 60;
}
I feel like if I could just get access to the UITableViewCell
in this method, then I could use the contentSize
property of the UITextView
in it, and return that. But I don't think that's possible at this point in the execution flow.
I can't just tweak that buffer, because it doesn't scale with the text size being returned by the get size function. The shorter the text, the more visible a larger buffer size is.
This is adjusting the height of the UITableViewCell
, but it's not showing all of the UITextView
inside of it. I've specified the width of the UITextView
in the sizeWithFont:constrainedToSize:lineBreakMode:
method, which is 280
. I've specified that I wish to have essentially no maximum height, so that it can word-wrap as much as it needs to, using the CGFLOAT_MAX
constant. I append a buffer of 20
units to the resulting height of the method call, because there is a 20
unit buffer above the UITextView
, in my Storyboard
, and I'd like to also have a 20
unit buffer below it.
The end result of all of this still has text being clipped off, though. Here is a picture of what I am talking about:
Any ideas?
Upvotes: 1
Views: 1009
Reputation: 7959
I'm going to go ahead and answer my question. The answer to this comes in two steps.
First, adjust the size of the UITextView
during your logic inside of the tableView:cellForRowAtIndexPath:
method. Make sure to do this after making any changes to the text in the UITextView
. I re-size my UITextView
using the following method, inside of a subclass of UITableViewCell
where self.text
is the text view:
- (void)resizeTextView {
// get the current frame size
CGRect frame = self.text.frame;
// set it to the height of the text view
frame.size.height = self.text.contentSize.height;
// set the new size of the text view
self.text.frame = frame;
}
Next, I specify the height of the UITableViewCell
inside of the tableView:heightForRowAtIndexpath:
method. This is where most of the mystery exists, because to get the height for this row you have to calculate the height of any text that is going to be displayed in the row, along with anything else you need to calculate the height of. In my scenario, is was a UITextView
. Without access to the UITableViewCell
instance in this method, you're forced to use something like sizeWithFont:constrainedToSize:lineBreakMode:
. But, I noticed this was not returning consistent heights for me. Or at least, not heights that seemed to make enough room for my text from the UITextView
. That was the problem, though. The text view has additional left and right padding as well as different line heights, or something, than the sizeWithFont
method uses.
So, after fudging the results of the sizeWithFont
method for awhile, I ended up with the following code:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// init the font that we use
UIFont *font = [UIFont fontWithName:@"SourceSansPro-Regular" size:16];
if (indexPath.section == 0) {
// get the text size of the thread
CGSize textSize = [_thread.text sizeWithFont:font constrainedToSize:CGSizeMake(280 - 16, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
// text height + padding
return textSize.height + 40;
} else if (indexPath.section == 1) {
// get the comment for this row
Comment *comment = [_comments objectAtIndex:indexPath.row];
// get the heights of the text areas
CGSize textSize = [comment.text sizeWithFont:font constrainedToSize:CGSizeMake(280 - 16, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
return textSize.height + 40;
}
return 60;
}
In the size constraint parameter, I subtract 16 units because the UITextView
has a padding of roughly 8 units on both the left and right sides. This will give us a closer result to what we expected for the height of the text.
I also add some padding to the final height, of 40 units, because the row itself needs some padding around the UITextView
.
There you go! Hope that helps.
Upvotes: 1