在 iOS 11 中使用 UITableView 在动态 UITextView 中跟随光标不再工作

Following cursor in dynamic UITextView with UITableView no longer working in iOS 11

我创建了一个 UITextView,它在 UITableViewCell 中动态调整大小作为一个人的类型。

在 iOS 10 上,UITextView 的光标会自动跟随,只需要很少的代码。

UITextViewDelegate 方法中 textViewDidChange: 我使用了这段代码,它更新了文本视图的大小而没有任何跳跃。

func textViewDidChange(_ textView: UITextView) {
    UIView.setAnimationsEnabled(false)
    self.tableView.beginUpdates()
    self.tableView.endUpdates()
    UIView.setAnimationsEnabled(true)
    self.tableView.contentOffset = currentOffset
}

在 iOS 11 中,这不再有效,当我键入时,光标会在键盘下方消失。请注意,当键盘出现时我不需要任何更改。

我知道 iOS11 中有与内容插图的工作方式相关的更改,但无法弄清楚我需要进行哪些更改才能使这项工作正常进行。

我应该在哪里进行这些更改以修复它?

--更新--

事实证明,删除所有这些代码可以解决我在 iOS 11 中的问题,并且 iOS 11 可以在我自动键入时处理向下滚动以跟随光标,没有任何问题。

我剩下的一个问题是,在 UITextView 停止更新 UITextViews 大小之前,我最多只能键入 28 行文本。

我正在使用 sabe 方法来更新 textView,它可以正常处理超过 28 行的文本,请确保您设置了所有这些属性:

textView.showsVerticalScrollIndicator = false
textView.isScrollEnabled = false

另外,当我定义我调用的 textView 文本时 textView.sizeToFit()

从XCode9开始,在tableview的size inspector中设置属性后,行的计算是自动的。Here, You can check this in image 我在 func textViewDidChange(_ textView: UITextView) 中做了一个改动 下面是我的代码

 func textViewDidChange(_ textView: UITextView) {
        UIView.setAnimationsEnabled(false)
        self.tableView.beginUpdates()
        self.tableView.endUpdates()
        UIView.setAnimationsEnabled(true)
        textView.sizeToFit()
    }

我在 iOS 11

时工作正常

你也可以看到约束,它们很简单,我正在使用它没有边距。

还有你的 textview 光标问题,我建议你 IQKeyboardManager,它会像这样管理所有事情。

class TextViewTableCell: UITableViewCell {

    @IBOutlet private weak var textView: UITextView! {
        didSet {
            textView.delegate = self
            textView.isScrollEnabled = false
        }
    }

    var textDidChangeHandler: (((text: String?, shouldScroll: Bool)) -> Void)?

    func textViewDidChange(_ textView: UITextView) {
        let size = textView.bounds.size
        let newSize = textView.sizeThatFits(CGSize(width: size.width, height: .greatestFiniteMagnitude))

        let shouldScroll = size.height != newSize.height ? textView.text.count == textView.selectedRange.location : false
        textDidChangeHandler?((text: textView.text, shouldScroll: shouldScroll))
    }
}

内部数据源cellForRow方法:

// dequeue TextViewTableCell cell
cell.textDidChangeHandler = { [weak self] (text, shouldScroll) in
    guard let this = self else { return }
    // do whatever actions with text if needed
    guard shouldScroll else { return }
    UIView.performWithoutAnimation {
        tableView.beginUpdates()
        tableView.endUpdates() 
    }
    tableView.scrollToRow(at: indexPath, at: .bottom, animated: false)
}

文本视图的最小高度限制也很好(例如 >=44)

我有同样的问题,一个 UITableViewController 和一个 UITableViewCell 在一个单元格中包含一个非滚动可编辑的 UITextView,并且光标会在 iOS11 中的键盘后面。在之前的 iOS 版本中运行良好。

我终于根据这篇文章和其他文章找到了解决方法:

- (void)textViewDidChange:(UITextView *)textView {
    // handle to UITableView
    UITableView *tableView = ....

    // tell table to resize itself
    [UIView performWithoutAnimation:^{
        [tableView beginUpdates];
        [tableView endUpdates];
    }];

    // get the caret rectangle so we can make sure we scroll it into view.
    CGRect unconvertedRect = [textView caretRectForPosition:textView.selectedTextRange.start];
    CGRect caretRect = [textView convertRect:unconvertedRect toView:tableView];
    // make the rect a little bigger so it's not at the extreme bottom of the view area
    caretRect.size.height += caretRect.size.height / 2;

    // this doesn't seem to work with a simple dispatch_async, but dispatch_after 0.1s seems to work.
    // why, i have no idea.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [tableView scrollRectToVisible:caretRect animated:NO];
    });
}

希望这对某人有所帮助...