I have implemented TableView with CustomCell in my app,
I want dynamic height of my UITableViewCell
according to text length in UITableViewCell
A'm looking for a long time how to determinate cell height properly, - looks like - it's a best solution, boundingRectWithSize and constrainedToSize often incorrectly calculated text height, you need to create UILabel than use sizeThatFits function, see below
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(8, 5, celllabelWidth, 9999)];
label.numberOfLines=0;
label.font = [UIFont fontWithName:fontName size:textSize];
label.text = @"celllabelTextHere";
CGSize maximumLabelSize = CGSizeMake(celllabelWidth, 9999);
CGSize expectedSize = [label sizeThatFits:maximumLabelSize];
return expectedSize.height;
}
Refer this link you are using Autolayout
else you can use below approach
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NewsVCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
if (cell == nil)
{
cell = [[NewsVCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
cell.titleCell.numberOfLines = 0;
cell.descriptionCell.numberOfLines = 0;
cell.titleCell.font = [UIFont systemFontOfSize:12.0f];
cell.descriptionCell.font = [UIFont systemFontOfSize:12.0f];
cell.descriptionCell.textColor = [UIColor lightGrayColor];
CGSize maximumLabelSize;
if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"])
{
maximumLabelSize = CGSizeMake(768, 10000);
}
else
{
maximumLabelSize = CGSizeMake(270, 10000);
}
NSString *newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
NSString *descriptionsText = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
CGSize expectedTitleLabelSize = [newsTitle sizeWithFont: cell.titleCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.titleCell.lineBreakMode];
CGSize expectedDescriptionLabelSize = [descriptionsText sizeWithFont:cell.descriptionCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.descriptionCell.lineBreakMode];
NSLog(@"cellForRowAtIndexPath :indexpath.row %d: height expectedTitleLabelSize:%f , indexpath.row height expectedDescriptionLabelSize:%f",indexPath.row,expectedTitleLabelSize.height,expectedDescriptionLabelSize.height);
if (newsTitle.length > 0)
{
cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height+20.0f);
}
else
{
cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height-20.0f);
}
if (descriptionText.length > 0)
{
cell.descriptionCell.frame = CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f);
}
else
{
cell.descriptionCell.frame = CGRectMake(20.0f, cell.titleCell.frame.size.height, 270.0f, 0.0f);
}
cell.descriptionCell.frame = CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f);
cell.titleCell.text = newsTitle;
cell.descriptionCell.text = descriptionsText;
NSLog(@"indexpath.row %d :title %@ ",indexPath.row,newsTitle);
NSLog(@"indexpath.row %d :description %@",indexPath.row,descriptionsText);
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
float totalHeight = 0.0f;
UILabel *labelTitle;
CGSize maximumLabelSize;
if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"])
{
labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 692.0f, 20.0f)]; // iPad
maximumLabelSize = CGSizeMake(768.0f, 10000.0f);
}
else
{
labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 270.0f, 20.0f)];
maximumLabelSize = CGSizeMake(270.0f, 10000.0f);
}
labelTitle.font = [UIFont systemFontOfSize:12.0f];
NSString *newsTitle;
NSString *newsDescription;
// cell.titleCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
// cell.descriptionCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
newsDescription = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
NSLog(@"indexpath.row %d :newsDescription.length %d",indexPath.row,newsDescription.length);
CGSize expectedTitleLabelSize;
CGSize expectedDescriptionLabelSize;
if (newsTitle.length > 0)
{
expectedTitleLabelSize = [newsTitle sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode];
totalHeight = totalHeight + 20.0f;
}
else
{
expectedTitleLabelSize = CGSizeMake(0.0f, 0.0f);
totalHeight = -20.0f;
}
if (newsDescription.length > 0)
{
expectedDescriptionLabelSize = [newsDescription sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode];
totalHeight = totalHeight + 20.0f;
}
else
{
expectedDescriptionLabelSize = CGSizeMake(0.0f, 0.0f);
totalHeight = -20.0f;
}
// NSLog(@"question: %f title:%f",expectedQuestionLabelSize.height,expectedTitleLabelSize.height);
totalHeight = expectedDescriptionLabelSize.height + expectedTitleLabelSize.height + 30.0f+20.0f;
return totalHeight;
}
To set automatic dimension for row height & estimated row height, ensure following steps to make, auto dimension effective for cell/row height layout.
UITableViewAutomaticDimension
to rowHeight & estimatedRowHeightheightForRowAt
and return a value UITableViewAutomaticDimension
to it)-
@IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Don't forget to set dataSource and delegate for table
table.dataSource = self
table.delegate = self
// Set automatic dimensions for row height
// Swift 4.2 onwards
table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = UITableView.automaticDimension
// Swift 4.1 and below
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Swift 4.2 onwards
return UITableView.automaticDimension
// Swift 4.1 and below
return UITableViewAutomaticDimension
}
For label instance in UITableviewCell
Try This, It worked like a charm! for me,
In viewDidLoad write this code,
-(void)viewDidLoad
{
[super viewDidLoad];
self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
In cellForRowAtIndexPath write this code,
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.numberOfLines = 0; // Set label number of line to 0
cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"menu"];
[cell.textLabel sizeToFit]; //set size to fit
return cell;
}
Hopes so this will help for some one .
Please, Look HERE - Dynamic Table View Cell Height and Auto Layout tutorial.
What you need:
Methods:
//this will calculate required height for your cell
-(CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath {
static UIYourClassCellName *sizingCell = nil;
//create just once per programm launching
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:@"identifierOfCell"];
});
[self configureBasicCell:sizingCell atIndexPath:indexPath];
return [self calculateHeightForConfiguredSizingCell:sizingCell];
}
//this method will calculate required height of cell
- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
[sizingCell setNeedsLayout];
[sizingCell layoutIfNeeded];
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
}
And call
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self heightForBasicCellAtIndexPath:indexPath];
}
Configuration of cell
- (void)configureBasicCell:(RWBasicCell *)cell atIndexPath:(NSIndexPath *)indexPath {
//make some configuration for your cell
}
After all operation i got next (text inside cell only as placeholder):
If you want to constrain the maximum height to 100 pt you have to use MIN
instead on MAX
:
CGFloat height = fmin(size.height, 100.0);