iOS 8 auto-sizing UITableViewCell with UITextView

前端 未结 6 1534
余生分开走
余生分开走 2021-02-12 12:11

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

// in viewDidLoad:
tableView.rowHeigh         


        
相关标签:
6条回答
  • 2021-02-12 12:52

    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)
        }
    }
    
    0 讨论(0)
  • 2021-02-12 12:54

    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.

    0 讨论(0)
  • 2021-02-12 12:57

    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.

    0 讨论(0)
  • 2021-02-12 12:57

    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];
            }
        }
    
    0 讨论(0)
  • 2021-02-12 13:01

    The tableView has to be informed that the textView has changed. Other posts usually answer a "static" textView problem. However, if you are typing inside a table, the cell needs to grow as the textView grows as you type. The textView grows by disabling scrolling. The cell grows by setting the textView's top and bottom constraints to those of the contentView of the cell. This will work once, once the table loads. However to tell the tableView to grow in real time, you have to do in the textView's didChange delegate call

    func textViewChanged(onCell cell: YourCustomCell) {
        UIView.setAnimationsEnabled(false)
        tableView.beginUpdates()
        tableView.endUpdates()
        UIView.setAnimationsEnabled(true)
    }
    

    This will work as you expect. The cell will grow as you type and there won't be a "bouncing".

    0 讨论(0)
  • 2021-02-12 13:01

    You should disable scroll from your UITextView

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