Dh S
Dh S

Reputation: 13

Dynamic height UITableViewCell auto layout

I have a custom UITableViewCell with only one UILabel. The UILabel is potentially too long to fit as a single row, so I have to dynamically set the height of UITableViewCell.

I set leading, top, and height(Greater or equal) constraints of UILabel. Am I missing any constraints?

ProductDetailDescriptionTableViewCell *cell = (ProductDetailDescriptionTableViewCell *)[self productDetailDescriptionCellInTableView:tableView
                                                                                                      indexPath:indexPath];

CGSize cellSize = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

return cellSize.height + 1;

This is calculate height code in tableView:heightForRowAtIndexPath:

I also set preferredWith of UILabel.

When I run my code, the height of cell is 0, label`s frame is

(0,-21,42,21)

I wish someone can help. Thank you very much!!!

Upvotes: 1

Views: 1325

Answers (4)

iDhaval
iDhaval

Reputation: 3205

If you want to just display text into label you do not have to make custom cell.

Just make number of line of UILabel to 0(zero)

Example

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

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}

cell.textLabel.text = @"This Is an example for dynamic height of UITableviewcell and UILabel in UITableView";
cell.textLabel.numberOfLines = 0;
return cell;

}

You do not have to specify heightForRowAtIndexPath Method

Upvotes: 0

József Vesza
József Vesza

Reputation: 4795

Update

I have created an example project for you, check it here.

Original answer

I think the simplest approach is the following:

  1. Define leading, top, trailing, and bottom constraints between your label, and the cell's content view (no need to constrain the height).

Constraints

  1. Now on your label, set the number of lines to 0 (meaning that it will fit its text into as many rows as needed):

Lines

This way, it should always fit within your table view cell, and the text won't be truncated. I'm not sure that setting the row height to automatic like, since it's supposed to be the default, but you can do it like this: self.tableView.rowHeight = UITableViewAutomaticDimension;

If you run into any issues, I recommend this terrific article on self sizing cells.

Upvotes: 0

Renish Dadhaniya
Renish Dadhaniya

Reputation: 10752

May be it's logic help full for you. Make Sure your label line is set 0.(label.numberOfLines = 0).It's work for me.

//Count Cell Size Here - It’s depend on content size of label. Put requiredHeight method in Tableviewcell class.
    - (CGFloat)requiredHeight
    {
        CGSize labelSize = [label.text sizeWithFont: [label font]
                                              constrainedToSize: CGSizeMake(300.0f, 300.0f)
                                                  lineBreakMode: NSLineBreakByTruncatingTail];

        int RowHeight = 30.0f + labelSize.height;

        if (RowHeight < 44) {
            if ([UIScreen mainScreen].bounds.size.width == 320) { // iPhone4 & iPhone5
                 return 45.0f;
            } else if([UIScreen mainScreen].bounds.size.width == 375){ // iPhone6
                 return 54.0f;
            }else{// iPhone6Plus
                 return 59.0f;
            }

        }else{

            if ([UIScreen mainScreen].bounds.size.width == 320) { // iPhone4 & iPhone5
               return 30.0f + labelSize.height;
            } else if([UIScreen mainScreen].bounds.size.width == 375){ // iPhone6
                //return 54;
                return 40.0f + labelSize.height;
            }else{// iPhone6Plus
               //return 59;
                 return 45.0f + labelSize.height;
            }
        }
    }


    //Call your custom cell class here
    - (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

         ATableViewCell *cell = (ATableViewCell*)[self tableView:self->tableView cellForRowAtIndexPath:indexPath];
         return [cell requiredHeight];

    }

Upvotes: 0

Jeshua Lacock
Jeshua Lacock

Reputation: 6668

Change the frame of the special cell(s) in like:

 float longLabelRowHeight; // Just for demonstration

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    CGSize constraint = CGSizeMake(self.frame.size.width, 9999);
    CGSize size = [label.text sizeWithFont:label.font 
           constrainedToSize:constraint 
               lineBreakMode:UILineBreakModeWordWrap];

    longLabelRowNumber = indexPath.row; //Just for demonstration

    longLabelRowHeight = size.height;

    if (longLabelRowHeight > 44.f) { // or whatever size
        cell.frame.size = CGSizeMake(self.frame.size.width, longLabelRowHight)
    }
}

Also be sure to return the custom height like:

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

    if (indexPath.row == longLabelRowNumber) { //Just for demonstration
        return longLabelRowHeight;
    }
    else {
        return kNormalCellHeight;
    }
}

Upvotes: 0

Related Questions