在iOS 8自动高度的单元格内输入时,UITableView跳转到endUpdates上

时间:2015-03-07 17:39:30

标签: ios uitableview ios8

我正在使用iOS 8自行调整单元格(tableView.rowHeight = UITableViewAutomaticDimensiontableView:estimatedHeightForRowAtIndexPath:)组合。它很有效,直到我开始在单元格内输入内容。当我打字时,我正在调用beginUpdates / endUpdates对来调整我的单元格大小(文本视图随着我的输入而增长,并在我删除时缩小)但每次调用都会导致错误跳到表格视图的顶部。如果我删除了beginUpdates / endUpdates对,那么它就不会跳转,但我的单元格在我输入时不会调整大小。

以下是该问题的演示:

enter image description here

如果我没有跳到表格视图的顶部,我怎样才能让我的单元格正确调整大小?我只针对iOS> = 8,因此我不需要任何iOS 7兼容性。

5 个答案:

答案 0 :(得分:14)

我正在为聊天应用程序实现完全相同的功能并获得与您现在获得的相同的问题。这件事帮助了我。如果这对您有用,请告诉我。

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)

答案 1 :(得分:2)

我发现solution from Manoj Aher工作正常 - 文本根本没有跳转。但在我的情况下,我不得不延长用户可能输入更多文本的情况(以便表格单元格大于表格的可见部分),然后返回在开头或中间某处编辑此文本。所以我必须将表格单元格滚动到顶部或中间,具体取决于用户输入的位置,以保持打字位置可见。

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

var cellIndexChosenForEdition: NSIndexPath
...

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

在shouldChangeTextInRange或用户类型时调用的任何其他方法(此处显示方法将在视图控制器符合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高度总是等于单元格高度而且从不滚动。

答案 2 :(得分:1)

我遇到了同样的问题,并且只能在内容的内在大小实际发生变化时执行调整大小/更新通知,从而最小化(但不能消除)跳转,例如:

夫特

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()
    }
}

目标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];
    }
}

答案 3 :(得分:0)

表格单元格的重置框架是否开始编辑?如果是,那么有时由于内存分配变量deallocate可以检查变量。使用断点并检查无法根据您的要求更改的变量值。

答案 4 :(得分:0)

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