在 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];
});
}
希望这对某人有所帮助...
我创建了一个 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];
});
}
希望这对某人有所帮助...