我在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)
}
}
}
唯一的问题是,当我在底部添加最后一行或几个空行时,表视图不会滚动。但是如果我在这个空行添加任何符号,它会滚动。
感谢您的帮助。
答案 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)
}
}