UITableView在iOS 8自动高度的单元格内input时在endUpdates上跳转到顶部

我正在使用iOS 8自我大小的单元格( tableView.rowHeight = UITableViewAutomaticDimensiontableView:estimatedHeightForRowAtIndexPath:组合。 它工作得很好,直到我开始在单元格内input内容。 当我打字的时候,我打电话给beginUpdates / endUpdates对来调整我的单元格的大小(文本视图随着我的input而增长,当我删除的时候会缩小),但是每次调用都会导致跳转到表格视图顶部。 如果我删除beginUpdates / endUpdates对,那么它不会跳转,但我的单元格不会调整,因为我键入。

这是一个问题的演示:

在这里输入图像说明

我怎样才能让我的单元格正确调整,因为我键入而不是跳转到表视图的顶部? 我只是针对iOS> = 8,所以我不需要任何types的iOS 7的兼容性。

我正在实现聊天应用程序完全相同的事情,并得到同样的问题,你现在正在得到。 这件事帮了我。 让我知道这是否也适用于你。

 UIView.setAnimationsEnabled(false) tableView.beginUpdates() cell.textView.scrollRangeToVisible(NSMakeRange(cell.textView.text.characters.count-1, 0)) tableView.endUpdates() UIView.setAnimationsEnabled(true) tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: false) 

我遇到了同样的问题,当内容的内在大小实际发生变化时,只能通过resize/更新通知来最小化(但不能消除)跳转,例如:

迅速

 var textViewHeight: CGFloat = 0.0 // Set in viewWillAppear as below ... func textViewDidChange(textView: UITextView) { let newHeight = textView.intrinsicContentSize().height if textViewHeight != newHeight{ textViewHeight = newHeight tableView.beginUpdates() tableView.endUpdates() } } 

Objective-C的

  CGFloat textViewHeight = 0.0; // Set in viewWillAppear as below ... (void)textViewDidChange:(UITextView *)textView { CGFloat newHeight = [textView intrinsicContentSize].height; if (textViewHeight != newHeight){ textViewHeight = newHeight [tableView beginUpdates]; [tableView endUpdates]; } } 

表格视图单元在文本上的重置框是否开始编辑? 如果是的话,那么你可以检查你的variables有时是由于内存分配variables释放的。 使用断点并检查不能根据您的要求更改的variables值。

自动布局有一些相关的缺点。 当你开始input时,它会跳转,因为所有其他的单元格都在调整它们的大小,所以如果你只在运行时计算单元格的大小,那将会更好。

我发现Manoj Aher的解决scheme很好 – 文本不会跳跃。 但在我的情况下,我不得不延长的情况下,用户可能会input更多的文本(以便表格单元格比表的可见部分大),然后返回编辑此文本开始或中间的某处。 所以我必须滚动表格单元格到顶部或中间,这取决于用户在哪里打字,以保持打字位置可见。

首先,以任何方便的方式记住单元格的indexPath。 例如:

 var cellIndexChosenForEdition: NSIndexPath ... func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { cellIndexChosenForEdition = indexPath ... } 

在shouldChangeTextInRange或任何其他方法,当用户types(这里显示的方法将被称为当您的视图控制器符合UITextViewDelegate协议时)调用:

 func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { ... UIView.setAnimationsEnabled(false) MyTableView.beginUpdates() MyTableView.endUpdates() UIView.setAnimationsEnabled(true) if let textStartPosition: UITextPosition = textView.selectedTextRange?.start { let cursorPosition = textView.offsetFromPosition(textView.beginningOfDocument, toPosition: textStartPosition) if textView.text.characters.count - cursorPosition < 170 { table_create_issue.scrollToRowAtIndexPath(cellIndexChosenForEdition, atScrollPosition: .Bottom, animated: false) } else if cursorPosition > 200 { table_create_issue.scrollToRowAtIndexPath(cellIndexChosenForEdition, atScrollPosition: .Middle, animated: false) } else { table_create_issue.scrollToRowAtIndexPath(cellIndexChosenForEdition, atScrollPosition: .Top, animated: false) } } ... } 

*常数200和170应该改变,以适应你的具体情况

**我没有使用scrollRangeToVisible,因为我的textView高度始终等于单元格高度,从不滚动。