2

I am working on a chat application which shows the message and image of user. I have a table view and a custom cell in it.The cell has a UIlabel and UIImage. I tried various methods to resize the cell height dynamically based on the content text of label .I have set the numberofLines=0 in the storyboard itself and set height of cell a constant so that multiple lines can fit in. But it does not show multiple lines and as for height I used auto dimension but it didn't work as well . I also used the following link And I am using a custom cell of type messageTableViewCell which has a property of label inside it.

Here is the snapshot :-image

My code in viewcontroller.m

- (void)viewDidLoad
{

   self.tableView.estimatedRowHeight = 100.0;

   self.tableView.rowHeight = UITableViewAutomaticDimension;
}

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

     messageTableViewCell *cell = [self.messageTableView dequeueReusableCellWithIdentifier:@"cell"];

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

    cell.messageLabel.text = [_messages objectAtIndex:indexPath.row];
    cell.messageLabel.lineBreakMode = NSLineBreakByWordWrapping;
    cell.messageLabel.numberOfLines=0;
    [cell.messageLabel sizeToFit];
    return cell;
}

EDIT

Instead of label I inserted a textview in the cell and modified it to :

- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth,     MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth),   newSize.height);
    textView.frame = newFrame;
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath
{
    static messageTableViewCell *sizingCell = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sizingCell = [self.messageTableView  dequeueReusableCellWithIdentifier:@"cell"];
   });

    sizingCell.textMessage.text=_messages[indexPath.row];
    CGFloat fixedWidth = sizingCell.textMessage.frame.size.width;
    CGSize newSize = [sizingCell.textMessage     sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = sizingCell.textMessage.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    CGFloat height= newFrame.size.height;
    NSLog(@"%f is height ",height);
    return height+5.0f;
}

But it is also not working and it cut off the upper half of text.

Community
  • 1
  • 1
user2714823
  • 607
  • 5
  • 15
  • 29
  • 1
    Try this excellent explanation: http://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights – koen Feb 02 '15 at 22:03

4 Answers4

5

Try this if you are working on above iOS 8. It works for me.

cell.messageLabel.text = [_messages objectAtIndex:indexPath.row];
cell.messageLabel.lineBreakMode = NSLineBreakByTruncatingTail;
cell.messageLabel.numberOfLines=0;
return cell;

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 10.0;
}
Pang
  • 9,564
  • 146
  • 81
  • 122
ahsan
  • 95
  • 6
  • 13
  • 1
    I did try solutions of [Zure](http://candycode.io/self-sizing-uitextview-in-a-uitableview-using-auto-layout-like-reminders-app/) and [Ray](https://www.raywenderlich.com/129059/self-sizing-table-view-cells), but they not helped until your answer comes. Many thanks. – samthui7 Oct 22 '16 at 05:32
4

http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout

This is probably one of the best tutorials on the subject that I have come across. It explains everything step by step so you can adapt things to fit your need.

Numan Tariq
  • 1,296
  • 1
  • 9
  • 18
  • Tried doing it but not helping :\ – user2714823 Feb 02 '15 at 20:08
  • It would be helpful to know what exactly is not working. Also, see the SO question that is linked by Koen in comment to your question. That is an excellent resource. The sample code in that one handles iOS 8 and 7 and you can combine them to support both. – Numan Tariq Feb 03 '15 at 09:42
3

Try this:

- (float)getMessageSize:(NSString *)text Width:(float)textWidth
{
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text
        attributes:@{
            NSFontAttributeName: [UIFont fontWithName:fontNameRefrig size:19.0]
        }];

    CGRect rect = [attributedText boundingRectWithSize:(CGSize){textWidth, CGFLOAT_MAX}
        options:NSStringDrawingUsesLineFragmentOrigin
        context:nil];
    CGSize finalSize = rect.size;
    return finalSize.height;
}
Pang
  • 9,564
  • 146
  • 81
  • 122
KARTHIK RA
  • 469
  • 2
  • 8
  • Just to note, for me the link to raywenderlich.com didn't work at all. Your method worked perfectly, with a little adjustment to take the additional height of the cell into account. – JamEngulfer Aug 09 '15 at 23:42
0

try this code

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

return [customcell getCellHeightForText:@"text"];
}


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

 cell = [ tableView dequeueReusableCellWithIdentifier : @"customCell" ] ;
  CGRect  rect=cell.frame;
  rect.size.height = [customcell getCellHeightForText:@"text"];
 cell.frame=rect;
return cell;
}

on customcell.m file

 +(NSInteger) getCellHeightForText:(NSString *) text {
float totalHeight = 0;
float topMargin = 35;
float bottomMargin = 30;
CGSize textSize = [text calculateSize:12.0 maxWidth:195 maxHeight:0 lineBreakMode:NSLineBreakByWordWrapping];
totalHeight = totalHeight + textSize.height + topMargin + bottomMargin;
return totalHeight;
}
amit gupta
  • 1,167
  • 12
  • 29