How do I tell my UITableViewCell to “auto-resize” when its content changes?

In my cell.xib, I have a label, with constraints to all its sides. I’ve set that label to lines = 0 and line-break = word wrap. Then, I do this to my TableView:

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

Everything works great, and my UITableViewCell is auto-height. If the text is long, then my tableView intelligently calculates the size.

  • UICollectionView Flow layout no fixed row height
  • When hiding the statusbar my navigation bar moves up in iOS7
  • Integrate iAd pre-roll video integration in my app?
  • TextField Autocompletion with JSON Response
  • How to create an umbrella framework in iOS SDK?
  • How can we have different Info.plist files for different environments such as Dev, Test, Staging, and Prod?
  • The problem is — how do I tell my UITableView to “re-calculate” the size once the content changes in the cell?

    My cell could call its delegate, and in this delegate, I’d like the TableView to re-draw the height.

    Right now, the content in my cells change constantly, but the cell height never changes.

    8 Solutions Collect From Internet About “How do I tell my UITableViewCell to “auto-resize” when its content changes?”

    There is a documented way to do this. See UITableView.beginUpdates() documentation:

    You can also use this method followed by the endUpdates method to animate the change in the row heights without reloading the cell.

    So, the correct solution is:

    tableView.beginUpdates()
    tableView.endUpdates()
    

    Also note that there is a feature that is not documented – you can add a completion handler for the update animation here, too:

    tableView.beginUpdates()
    CATransaction.setCompletionBlock {
       // this will be called when the update animation ends
    }
    
    tableView.endUpdates()
    

    However, tread lightly, it’s not documented (but it works because UITableView uses a CATransaction for the animation).

    I’ve found the best way to get it to check heights is to call, after whatever text change has been made, in order:

    self.tableView.beginUpdates()
    self.tableView.endUpdates()
    

    This causes the tableView to check heights for all visible cells and it will cause changes to be made as needed.

    I think the simplest solution is to reload that specific cell. For example:

    - (void)yourDelegateMethodOfCell:(UITableViewCell *)cell {
        NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
        //If cell is not visible then indexPath will be nil so,
        if (indexPath) {
            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }
    }
    

    You can get automatic cell height by this code

    tableView.beginUpdates()
    // add label text update code here 
    // label.numberOfLines = label.numberOfLines == 0 ? 1 : 0
    tableView.endUpdates()
    

    Below is the reference to this solution with demo :

    GitHub-RayFix-MultiLineDemo

    I got your point, and I met the problem before.
    Your cell is in AutoLayout, and you wish the cell changes by itself. Here is recommended answer for that: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights , so we don’t talk about that again.

    So here we focus on your problem.

    Since the content of your cell changes constantly, which means the content has updated. Here we suppose the content is a label. We set the label’s text, and surely the label’s height maybe change.

    Here comes the point: How does the label’s change inform the cell to update?

    We use AutoLayout, surely we have to update the constraint of height for the label.

    And I think it will work!

    Below is the detail step:
    1. We setup the constraints for the cell’s subviews.(I think it’s done)
    2. One of the label’s height is changed by itself.(I think it’s done too)
    3. We get the new height of the label, and update the constraint of height for the label.(what we have to do)

    Seems you wanted to reload the particular cell/cells based on content changes

    Here we have a couple of options

    1) Need to reload the entire table view .

    or else

    2) Reload particular cell/cells based on content changes.

    But the preferred option would be reloading the particular cell,

    Why because
    when you asked your UITableView instance to reload a couple of cells,tableview will asks its datasource(-tableView:cellForRowAtIndexPath:) to get the updated content,so that the reloaded cells will have the updated size & Updated content aswell.

    Try to reload the cells when the content/height need to update based on content

    Hope that helps!
    Happy coding 🙂

    Take a look at this answer : Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

    How to achieve dynamic cell size is described very thorough there.

    As a suggestion for testing try adding setNeedsLayout to:

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

    or

    - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath 
    

    You can resize your cell height by implementing below method only

     - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return UITableViewAutomaticDimension;
    }