UITableView中灵活的可编辑UITextView:不会显示键盘下的最后一行

时间:2018-01-24 15:03:05

标签: swift uitableview uitextview

我在UITableViewCell中有一个灵活的可编辑UITextView。可以在https://github.com/AlexChekanov/TextViewInTableView

找到简单项目的完整源代码

一切正常。每次TextView高度改变时我都会重新计算单元格高度,然后将表格滚动到光标。

class TextViewTableViewCell: UITableViewCell, UITextViewDelegate {

    weak var tableView: UITableView?
    var textViewHeight: CGFloat?

    @IBOutlet weak var textView: UITextView!

    override func awakeFromNib() {
        super.awakeFromNib()

        textViewHeight = textView.intrinsicContentSize.height
        textView.becomeFirstResponder()
    }


    func textViewDidChangeSelection(_ textView: UITextView) {

        guard let tableView = tableView else { return }

        selfUpdate(in: tableView)
        scrollToCursor()
    }

    func selfUpdate(in tableView: UITableView) {

        // Do nothing if the height wasn't change
        guard textViewHeight != textView.intrinsicContentSize.height else { return }

        textViewHeight = textView.intrinsicContentSize.height
        // Disabling animations gives us our desired behaviour
        UIView.setAnimationsEnabled(false)
        /* These will causes table cell heights to be recaluclated,
         without reloading the entire cell */
        tableView.beginUpdates()
        tableView.endUpdates()

        UIView.setAnimationsEnabled(true)
    }

    func scrollToCursor() {

        guard let tableView = tableView else { return }

        if let currentCursorPosition = textView.selectedTextRange?.end {
            print(currentCursorPosition)

            let caret = textView.caretRect(for: currentCursorPosition)

            print(caret)

            tableView.scrollRectToVisible(caret, animated: false)
        }
    }
}

唯一的问题是,当我在底部添加最后一行或几个空行时,表视图不会滚动。但是如果我在这个空行添加任何符号,它会滚动。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

UITextView默认允许滚动,这可能是问题所在。当UITextView中的文本大小大于UITextView本身时,它允许您滚动。这可能与UITableView的滚动冲突。只需使用它就可以安全:

self.textView.isScrollEnabled = false
self.textView.isEditable = false

答案 1 :(得分:0)

我找到了解决方案:

class TextViewTableViewCell: UITableViewCell, UITextViewDelegate {

    weak var tableView: UITableView?
    var textViewHeight: CGFloat?

    @IBOutlet weak var textView: UITextView!

    override func awakeFromNib() {
        super.awakeFromNib()

        textViewHeight = textView.intrinsicContentSize.height
        textView.becomeFirstResponder()
    }

    func textViewDidChangeSelection(_ textView: UITextView) {

        guard let tableView = tableView else { return }

        selfUpdate(in: tableView)

        // Here is the trick!
        if textView.textStorage.string.hasSuffix("\n") {
            CATransaction.setCompletionBlock({ () -> Void in
                self.scrollToCaret(textView, animated: false)
            })
        } else {
            self.scrollToCaret(textView, animated: true)
        }
    }

    func scrollToCaret(_ textView: UITextView, animated: Bool) {

        guard let tableView = tableView else { return }

        guard let currentCursorPosition = textView.selectedTextRange?.end else { return }

        var caret = textView.caretRect(for: currentCursorPosition)
        caret.size.height += textView.textContainerInset.bottom * 2
        tableView.scrollRectToVisible(caret, animated: animated)
    }

    func selfUpdate(in tableView: UITableView) {

        // Do nothing if the height wasn't change
        guard textViewHeight != textView.intrinsicContentSize.height else { return }

        textViewHeight = textView.intrinsicContentSize.height

        // Disabling ansimations gives us our desired behaviour
        UIView.setAnimationsEnabled(false)
        /* These will causes table cell heights to be recaluclated,
         without reloading the entire cell */
        tableView.beginUpdates()
        tableView.endUpdates()

        UIView.setAnimationsEnabled(true)
    }
}