iOS 8 auto-sizing UITableViewCell with UITextView

2019-03-23 02:06发布

问题:

iOS 8 introduced a way for tableViews to automatically adjust their cell's height based on their content (via AutoLayout).

// in viewDidLoad:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44.0

I already got it working with labels, images, etc.

However, I can not figure out a way for the table view cell to grow automatically as soon as a cell's text view changes?

Some more information on the setup: The UITextView inside a cell has horizontal and vertical constraints to the table view cell's contentView. I also disabled scrolling for the text view.

I have also tried to change the height constraint of the cell manually, but the cell would not adopt those changes as well.

回答1:

If everything is set up properly (Auto Layout constraints) you do not have to calculate anything yourself.

All you have to do is disable UITextView's scrolling enabled property then on textViewDidChange call tableView.beginUpdates() and tableView.endUpdates().

For a detailed explanation, check out a post I wrote which also includes a working sample project.



回答2:

Reload the cell in the textViewDidBeginEditing: method of your UITextViewDelegate

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForItem:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];

Obviously you should change the indexpath to the correct one for your cell. This will get the cell to update its constraints and resize itself.



回答3:

Solution for Swift 4

func textViewDidChange(_ textView: UITextView) {
    let fixedWidth = textView.frame.size.width
    let oldSize = textView.frame.size
    let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT)))
    if oldSize.height != newSize.height {
        UIView.setAnimationsEnabled(false)
        var newFrame = textView.frame
        newFrame.size = CGSize(width: fmax(newSize.width, fixedWidth), height: newSize.height)
        textView.frame = newFrame
        self.tableView.beginUpdates()
        self.tableView.endUpdates()
        UIView.setAnimationsEnabled(true)
    }
}


回答4:

This is the function I use, which solves the problem of the table view bouncing back after every keystroke.

 - (void)textViewDidChange:(UITextView *)textView {

    CGFloat fixedWidth = textView.frame.size.width;
    CGSize oldSize = textView.frame.size;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
        // Resize cell only when cell's size changes, to prevent bouncing back and forth.
        if (oldSize.height != newSize.height) {
        [UIView setAnimationsEnabled:NO];
        CGRect newFrame = textView.frame;
        newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
        textView.frame = newFrame;
        [self.tableView beginUpdates];
        [self.tableView endUpdates];
        [UIView setAnimationsEnabled:YES];
        }
    }


回答5:

You should disable scroll from your UITextView