Muhammad Umair
Muhammad Umair

Reputation: 593

Increase height of tableview cell according to amount of UILabel text

I want to change the height of my tableview cell according to the amount of text by using auto layout. I have tried the following code but it doesn't work:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    AddTaskDetails *addTaskDetail = (self.tasksArray)[indexPath.row];
    CGFloat height;
    float textcount = [addTaskDetail.taskDetail length];
    if(textcount>60)
    {



            height = textcount-20;

        NSLog(@"%d,%f",indexPath.row,height);
    }
    else
    {
        height = 70;
    }
    return height;
}

Upvotes: 2

Views: 845

Answers (8)

Himanshu padia
Himanshu padia

Reputation: 7730

Use below code to get better result with/without Autolayout. Need to calculate font height of label and set the position as per your requirement.

It will also helpful for calculate collectionView's dynamic cell height.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize constraint = CGSizeMake(screenWidth - 62, 20000.0f);
    CGSize size;
    NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
    CGSize boundingBox = [string boundingRectWithSize:constraint
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{NSFontAttributeName:self.titleLabel.font}
                                              context:context].size;
    
    size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));
    return size.height + 16;
}

Upvotes: 0

Hassan Aftab
Hassan Aftab

Reputation: 644

You don't have to do it programmatically. You can easily do it using Autolayouts in interface builder.

  • Just add a UITableViewCell to you UITableView
  • Set its style to custom
  • Make sure its size in Size inspector is default
  • Add a UILabel to this cell
  • Set its Top, Bottom, Left, Right Constraints
  • In size inspector set preferred width to explict
  • In attribute inspector set number of lines to "0"

Then add these lines in viewDidLoad()

tableView.estimatedRowHeight = 40.0
tableView.rowHeight = UITableViewAutomaticDimension

Also implement these delegate methods

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 44
}

Upvotes: 1

Yatendra
Yatendra

Reputation: 1316

Try with this... it will help you.

 NSString *classSubjecttxt =@"Some text";
 CGSize requiredSizeSubjetc =[classSubjecttxt sizeWithFont:[UIFont fontWithName:@"Trebuchet MS" size:12] constrainedToSize:CGSizeMake(labelwidth, CGFLOAT_MAX)];



        int height=YOUR DEFAULT HEIGHT;

         if(requiredSizeSubjetc.height >18){

            height=height-18+ceil(requiredSizeSubjetc.height);
        }

        return height;

Upvotes: 1

Akash KR
Akash KR

Reputation: 798

1.Create a custom cell class. Create outlets for label/imageview.

2.Add this method in your custom cell class.

-(void) layoutSubviews
{
 [super layoutSubviews];
 [self.contentView layoutIfNeeded];
 self.yourLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.sentenceLabel.frame);
}

3.In your view controller class,create a property of your custom cell class.

-(DynamicTblVCell *)prototypeCell
 {
  if(!_prototypeCell)
   {
      _prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:@"DynamicTblVCell"];
   }
return _prototypeCell;
 }

4. In your viewDidLoad add these two lines:

self.tableView.estimatedRowHeight = 100.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;

5. And finally do this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
  static NSString *cellIdentifier = @"DynamicTblVCell";
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

//to configure a cell before it is displayed
 [self configureCell:cell forRowAtIndexPath:indexPath];

 return cell;
 }

-(void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:  (NSIndexPath *)indexPath
 {
  if([cell isKindOfClass:[DynamicTblVCell class]])
   {
    DynamicTblVCell * textCell = (DynamicTblVCell *)cell;
    textCell.sentenceLabel.text = [NSString stringWithFormat:@"jhjshdjshdjhkjdhajsdhajsdh"];
    textCell.sentenceLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];  
   }
 }

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
 {
  [self configureCell:self.prototypeCell forRowAtIndexPath:indexPath];
  self.prototypeCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.bounds), CGRectGetHeight(self.prototypeCell.bounds));
  [self.prototypeCell layoutIfNeeded]; 

  CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

  return size.height+1;
}


-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
 {
   return UITableViewAutomaticDimension;
 }
  1. set number of lines for label to 0.
  2. Add constraints for top space, bottom space, left and right space. Do not add height constraint for label.

Upvotes: 0

Jatin Chauhan
Jatin Chauhan

Reputation: 1127

First of all you need to calculate height of your label.

You can get dynamic height of your label by calling with below functions:

-(CGFloat)getDynamicHeightOfLabelWithFont:(UIFont *)font withText:(NSString *)text withFrame:(CGRect)initialFrame
{
    UILabel *lblDummy = [[UILabel alloc] initWithFrame:initialFrame];
    lblDummy.font = font;
    lblDummy.lineBreakMode = NSLineBreakByWordWrapping;
    lblDummy.numberOfLines = 0;
    lblDummy.text = text;

    CGRect dummyFrame = initialFrame;

    dummyFrame.size = [lblDummy sizeThatFits:initialFrame.size];
    return dummyFrame.size.height;
}

You need to call this function on heightForRowAtIndexPath and return the height. and you need to set the frame on cellForRowAtIndexPath and set frame to your label.

Upvotes: 0

Piyush
Piyush

Reputation: 1544

- (CGFloat)getLabelHeight:(NSString*)textvalue
{
    if (![textvalue isEqualToString:@""]) {

        NSString *string=textvalue;

        string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

        UIFont *font = [UIFont systemFontOfSize:12];
        CGSize constraint = CGSizeMake(SCREENWIDTH/1.0,NSIntegerMax);
        NSDictionary *attributes = @{NSFontAttributeName: font};
        CGRect rect = [string boundingRectWithSize:constraint
                                           options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                        attributes:attributes
                                           context:nil];

        return rect.size.height;
    }
    else
    {
        return 20;
    }

}

Then You can get size by calling this :

AddTaskDetails *addTaskDetail = (self.tasksArray)[indexPath.row];
    CGFloat textHeight = [self getLabelHeight:[addTaskDetail valueForKey:@"YOURKEY"]];

Here You will get the text size of your text then return it to heightForRowAtIndexPath.

Upvotes: 0

Pankaj
Pankaj

Reputation: 344

You will need to use boundingRectWithSize:options:attributes:context on the string to be rendered.

This is a frequently asked question and you may find code snippets when you search for 'UITableViewCell with dynamic height'.

Upvotes: 2

Mathews
Mathews

Reputation: 743

You better don't hardcode the height required for the string. Rather use the attributed text height property.

let attributes = [NSFontAttributeName : textFont,
        NSForegroundColorAttributeName : UIColor(
            red:25/255,
            green:176/255,
            blue:37/255,
            alpha:1.0)]


let attrString:NSAttributedString? = NSAttributedString(string: yourString, attributes: attributes)
let rect:CGRect = attrString!.boundingRectWithSize(CGSizeMake(280.0,CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, context:nil )
return rect.height

Upvotes: 2

Related Questions