Reputation: 519
I have looked at several questions asking to adjust row height based on cell content. But in my case, I have 10 labels in one cell and each label has fixed width. Labels must wrap the text if not fit to label width. So row height depends on all 10 label's text content. That means I have to calculate height of every label for given text and take maximum height amongst all labels as row height. I have to do this for all rows. This looks to me an insufficient solution. Is there any better solution?
Thanks,
Jignesh
Upvotes: 0
Views: 2913
Reputation: 7145
The UITableView
requires that you implement heightForRowAtIndexPath
in order to have a custom height for a table cell. This is because UITableView
calculates the total height of the table each time the data is reloaded. You could look to cache the row-height calculations as well if the data is static.
In your case I would recommend creating a data model class that represents all 10 label's worth of text and provide a helper function on that data model class that you can call in heightForRowAtIndexPath
. The helper function would encapsulate the row height calculations perhaps something like this:
Let's say you have this for a data model class that represents the data in your rows:
@interface MyDataModelClass : NSObject
@property (strong, nonatomic) NSString *label1Text;
@property (strong, nonatomic) NSString *label2Text;
// ... etc
- (CGFloat)calculateLabelHeight;
@end
Then your calculateLabelHeight
method might look something like this (this is just pseudo code, obviously):
- (CGFloat)calculateLabelHeight {
CGFloat totalHeight = 0.0;
// Loop through your label texts calculating the variable sized height for each
// and adding some padding in between:
CGSize variableSize1 = [self.label1Text sizeWithFont:[UIFont systemFontOfSize:12.0] constrainedToSize:CGSizeMake(300, 400) lineBreakMode:NSLineBreakByWordWrapping];
CGSize variableSize2 = [self.label2Text sizeWithFont:[UIFont systemFontOfSize:12.0] constrainedToSize:CGSizeMake(300, 400) lineBreakMode:NSLineBreakByWordWrapping];
totalHeight = variableSize1 + padding + variableSize2 + padding; // and so on for all your labels.
return totalHeight;
}
Then in heightForRowAtIndexPath
you can do this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
MyDataModelClass *modelObject = [self.data objectAtIndex:indexPath.row];
// Assuming model object's label text properties have been set you can do this:
return modelObject.calculateLabelHeight;
}
It just occurred to me that one label might have a long string in it causing it to wrap and possibly overlay a second label. You may also want to add a method to a UITableViewCell
subclass called repositionLabels
or something that does this for you after you know each label text's height.
Unfortunately, I think this is the only way to calculate height for a cell. See this S.O. post for more info:
IOS: dynamic height with a custom uitableviewcell
Upvotes: 1
Reputation: 36
You need to calculate all heights before displaying cells. After that return row height for each row using:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
To calculate text size use:
[yourString sizeWithFont:constrainedToSize:lineBreakMode:]
Upvotes: 2