Resize UITableViewCell containing UITextView upon typing

后端 未结 11 2072
感动是毒
感动是毒 2020-12-23 10:19

I have an UITableViewController that contains a custom cell. Each cell was created using a nib and contains a single non-scrollable UITextView. I have added constraints insi

相关标签:
11条回答
  • 2020-12-23 10:51

    Inspired by the two previous answers, I found a way to solve my problem. I think the fact that I had a UITextView was causing some troubles with autoLayout. I added the following two functions to my original code.

    - (CGFloat)textViewHeightForAttributedText: (NSAttributedString*)text andWidth: (CGFloat)width {
        UITextView *calculationView = [[UITextView alloc] init];
        [calculationView setAttributedText:text];
        CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
        return size.height;
    }
    
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        UIFont *font = [UIFont systemFontOfSize:14.0];
        NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
        NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:self.sampleStrings[indexPath.row] attributes:attrsDictionary];
        return [self textViewHeightForAttributedText:attrString andWidth:CGRectGetWidth(self.tableView.bounds)-31]+20;
    }
    

    where in the last line 31 is the sum of my constraints to the left and right sides of the cell and 20 is just some arbitrary slack.

    I found this solution while reading this this very interesting answer.

    0 讨论(0)
  • 2020-12-23 10:54

    Tested on iOS 12

    I really tried a lot of solutions and finally found a good one here

    This works with animation and looks beautiful. The trick was the DispatchQueue.async block. I also used TPKeyboardAvoidingTableView to make sure the keyboard doesn't overlap anything.

    func textViewDidChange(_ textView: UITextView) {
        // Animated height update
        DispatchQueue.main.async {
            self.tableView?.beginUpdates()
            self.tableView?.endUpdates()
        }        
    }
    

    UPDATE

    I got strange jumping issues because of TPKeyboardAvoidingTableView. Especially when I scrolled to the bottom and then a UITextView got active. So I replaced TPKeyboardAvoidingTableView by native UITableView and handle the insets myself. The table view is does the scrolling natively.

    0 讨论(0)
  • 2020-12-23 10:55

    Check out the Objective C solution I have provided in the following link below. Simple to implement, clean, and no need for auto layout. No constraints needed. Tested in iOS10 and iOS11.

    Resize and move UITableViewCell smoothly without dismissing keyboard

    0 讨论(0)
  • 2020-12-23 10:56

    The solution almost everyone suggested is the way to go, I will add only a minor improvement. As a recap:

    1. Simply set the estimated height, I do it via storyboard:

    2. Make sure you have the constraints for the UITextView correctly set within the cell.

    3. In the func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

    I simply call: cell.myTextView.sizeToFit()

    0 讨论(0)
  • 2020-12-23 10:57

    Using Swift 2.2 (earlier versions would likely work too), if you set the TableView to use auto dimensions (assuming you're working in a subclassed UITableViewController, like so:

        self.tableView.rowHeight = UITableViewAutomaticDimension
        self.tableView.estimatedRowHeight = 50 // or something
    

    You just need to implement the delegate in this file, UITextViewDelegate, and add the below function, and it should work. Just remember to set your textView's delegate to self (so, perhaps after you've dequeued the cell, cell.myTextView.delegate = self)

    func textViewDidChange(textView: UITextView) {
        self.tableView.beginUpdates()
        textView.frame = CGRectMake(textView.frame.minX, textView.frame.minY, textView.frame.width, textView.contentSize.height + 40)
        self.tableView.endUpdates()
    }
    

    Thanks to "Jose Tomy Joseph" for inspiring (enabling, really) this answer.

    0 讨论(0)
  • 2020-12-23 11:01

    Previously beginUpdates/endUpdates were the advertised solution.

    Since iOS 11, performBatchUpdates is what has been recommended source.

    Calling performBatchUpdates after making a change to a cell's content works for me.

    0 讨论(0)
提交回复
热议问题