0

I have to show the list details in UITableview. But the listing is small for some cells and large/medium height for some other cells. (Like facebook feed) So Tableview have different height for each cell. How can i achieve this?

The list contains,

imageview,2 labels, textview (Label and textview lengths also increased based on its content. It will also affect the tableview cell height). So any help to achieve this would be greatful.

Thanks.

Thangavel
  • 216
  • 2
  • 10

2 Answers2

0
#define CELL_MARGIN 10.0f 

-(CGFloat)heightForTableView:(NSString*)text widthOfTableview:(CGFloat)tableViewWidth{
    CGSize constraint = CGSizeMake(tableViewWidth - (CELL_MARGIN * 2), 20000.0f);

    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    CGFloat height = MAX(size.height, 44.0f);

    return height + (CELL_MARGIN * 2);
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [self heightForTableView:cell.titleLabel.text widthOfTableview:CGRectGetWidth(tableView.frame)];// cell.textlable.text is your lable.text
}

This code might helps you :)

Yuyutsu
  • 2,509
  • 22
  • 38
  • I have tried this.But my tableview cell have labels and textviews.So tableview does not scrolling smoothly.Because i have called this almost 10 times for a single row.So tableview strucks. – Thangavel Apr 16 '15 at 06:30
  • check this link:http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout – Yuyutsu Apr 16 '15 at 06:31
  • You shouldn't use a constant cell width because it is not guaranteed to be always the same. For example on an iPhone 6+, landscape mode, or just the table view not occupying the full width of the screen. – Nikola Lajic Apr 16 '15 at 07:37
  • @MrNickBarker it working for me.. because I was used Auto-layout.. did you check for it.. – Yuyutsu Apr 16 '15 at 08:23
  • @Yuyutsu you are calculating the size of the text based on a constant. The cell width can change, and so your calculation will be wrong. You should be getting the width of the table view after it has been laid out instead of using a constant width. This code might work fine on some devices and some cases, but it is flawed. – Nikola Lajic Apr 16 '15 at 08:38
  • @MrNickBarker : You mean to say instead of using `CELL_WIDTH`. I used `tableView.frame.size.width` this right. – Yuyutsu Apr 16 '15 at 08:44
  • @Yuyutsu correct, or `CGRectGetWidth(tableView.frame)`. – Nikola Lajic Apr 16 '15 at 08:57
  • @MrNickBarker ok I will update that Answer thanks you :) and Is it right now? – Yuyutsu Apr 16 '15 at 08:58
0

Create your cells with their own .xib. Add the labels, textview imageviews etc as you want. Make sure to pin all them with constraints horizontally and vertically to the leading/trailing/top and bottom of the cell.

Now the trick is to tell autolayout to layout the contentView of the cell, and return the minimum height to fit its content. Since heightForRow is executed before the cell is loaded in cellForRow, we need to use a fakeCell to calculate the height.

To do this lets say, in our controller, we have a tableView showing cells of class DetailsTableViewCell with a nib created for it DetailsTableViewCell.xib :

1) Create a @property in your controller for a fakeCell.

@property (nonatomic, strong) DetailsTableViewCell *fakeCell;

2) In viewDidLoad, initialize it from them nib:

self.fakeCell = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass:@"DetailsTableViewCell" owner:nil options:nil].firstObject;

3) In heightForRowAtIndexPath:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    //grab fakeCell, style it with the data you want
    [self.fakeCell styleWithDetails:self.details];
    //and calculate the minimum height required to fit all content
    return [self minimumCellHeightToSatisfyConstraints:self.fakeCell];
}



-(CGFloat)minimumCellHeightToSatisfyConstraints:(UITableViewCell *)cell {
    //Makes sure cell's width is equal to tableView's width (can be wrong since they are in separated nibs)
    cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.bounds), CGRectGetHeight(cell.bounds));

    //Force autolayout to recalculate all subview's frames
    [cell layoutIfNeeded];

    //Get the minimum height required for the cell to fit all its content
    CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    return height;
}

Important: If you forget to pin all subviews in the .xib vertically from top to bottom to the cell, calling systemLayoutSizeFittingSize:UILayoutFittingCompressedSize will return 0 and won't work.

Pauls
  • 2,596
  • 19
  • 19