10

I have UITableviewCell subclass. In that cell, I have 2 labels (lblComment and lblDateTimeStampe) and one view to show rating stars. I want dynamic height of lblComment to fit all the text. It should expand & shrink in height depending on the length of comment. I have implemented this before but WITHOUT AutoLayout like below

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

    NSString *label =  self.userComment.commentText;
    CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15]
                          constrainedToSize:CGSizeMake(320, 9999) 
                              lineBreakMode:UILineBreakModeWordWrap];

    return stringSize.height+10;

} 

Now I am using AutoLayout feature.

How can I achieve this using Autolayout?

Any kind of help is appreciated. Thanks

gklka
  • 2,459
  • 1
  • 26
  • 53
iOSAppDev
  • 2,755
  • 4
  • 39
  • 77
  • Did you find a solution yet? If so please share. – eric Feb 17 '13 at 14:51
  • I didn't get any solution. So I end up adding UI elements programatically in cellForRowAtIndexPath & then used above method. Then works as per my requirements. – iOSAppDev Feb 20 '13 at 13:27
  • Take a look at my answer to this question here: http://stackoverflow.com/a/18746930/796419 – smileyborg Sep 20 '13 at 21:21

4 Answers4

3

Unfortunately Auto Layout won't help you with tableView:heightForRowAtIndexPath. You still have to implement that method.

You can use UIView's systemLayoutSizeFittingSize: method but that means you'd have to instantiate and configure a table view cell which can be quite costly. You could keep one off-screen though and reuse it for calculations. But at this point, you don't really save much in terms of development effort, so doing the calculations as you did before manually is probably the best/fastest way to do this.

Adrian Schönig
  • 1,786
  • 18
  • 26
  • 2
    When parsing data, I keep a UITableViewCell in the background, use it to calculate the height, and then store the height value in the object. By the time `tableView:heightForRowAtIndexPath` is called, the height has already been calculated for each data object. – Aaron Brager Jul 08 '13 at 20:27
0

You can use the freely available Sensible TableView framework. The framework automatically resizes the cells as their content grows. It also does that dynamically if the table view is already displayed.

Matt
  • 2,391
  • 2
  • 17
  • 18
0

I have implemented a solution to the same problem with using autolayout and it works.

First, you need to define heightConstraint for lblComment.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UIFont *font = [UIFont fontWithName:@"YourFontName" size:YourFontSize] ;
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setFont:font];
[calculationView setTextAlignment:NSTextAlignmentLeft];
[calculationView setText:lblComment.text];
int width = 0;
if(self.appDelegate.isDeviceiPhone)
    width = 284;
else
    width = 720;
CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
   return size.height;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
//initialize the cell..

UIFont *font = [UIFont fontWithName:@"YourFontName" size:YourFontSize];

UITextView *calculationView = [[UITextView alloc] init];
[calculationView setFont:font];
[calculationView setTextAlignment:NSTextAlignmentLeft];
[calculationView setText:cell.lblComment.text];

int width = 0;

if(self.appDelegate.isDeviceiPhone)
    width = 284;
else
    width = 720;

CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];

cell.lblDetailHeightConstraint.constant = size.height;

// the other stuff...
}

Hope this helps.

handet87
  • 549
  • 5
  • 22
-2

If you setup the constraints correctly in IB this should work. You should not have to add the elements programmatically although as you said that will work as well.

Assuming that you have label1(variable height), label2, and view1 in the tableviewcell in that order you should:

  1. Set fixed height constraints on label2 and view1
  2. Pin the bottom of view1 to the bottom of the cell
  3. Pin the vertical spacing of view1 and label2
  4. Pin the vertical spacing of label2 and label1
  5. Pin the top spacing of label1 to the top of the cell

Just make sure that you do NOT have a height constraint on label1, if you do it should only be greater than or equal to. With a configuration like this, you can continue using heightForRowAtIndexPath and label1 will expand and contract vertically based on the height of the cell.

Rick Roberts
  • 885
  • 11
  • 13