UITableView滚动到单元格刷新的顶部

时间:2015-05-07 18:19:37

标签: ios objective-c uitableview uiscrollview uitextview

我有一个UITableView,其中一个单元格的动态大小适合其中的UITextView。每当键入一个键时,单元格检查计算的高度是否增加,如换行符,因此它可以告诉表格需要重新计算单元格的高度。我用这段代码做到了。

- (void) createNoteCellViewDidUpdate: (CreateNoteCell*) cell {

    CGFloat newHeight = [self tableView:self.tableView heightForRowAtIndexPath:CreateNoteCellIndexPath];
    if (newHeight != CGRectGetHeight(cell.contentView.frame)) {
        [self.tableView beginUpdates];
        [self.tableView endUpdates]; // <- HERE IS WHERE THE CONTENT OFFSET CHANGES
    }
}

调整大小和表格边界符合预期。但它不仅仅是动画高度的变化,而是滚动到顶部。按下返回键时可以看到这一点。

table scrolling on cell resize

按键值观察,我发现当滚动视图的contentSize发生变化时,滚动视图contentOffset正在设置。并且在调用endUpdates方法时,contentSize会多次更改。当它改变时,它从正常高度变为相当大的高度,然后回到正常高度。我不知道它是否会因此而上升。我不知道从哪里开始。

4 个答案:

答案 0 :(得分:24)

哇,Josh Gafni的回答很有帮助;他应该得到一个赞成。我的解决方案是基于他的。这仍然感觉像是一个黑客,所以如果有人还有更好的方法来做到这一点,我仍然很有兴趣听到它。

首先我保存内容偏移量,然后开始更新。

CGPoint offset = self.tableView.contentOffset;
[self.tableView beginUpdates];
[self.tableView endUpdates];

这会激活单元格的高度变化并调整所有帧以适应约束。

接下来,我从tableView的图层中删除所有动画,因此顶部的动画停止。然后我将contentOffst重置为之前的状态。

[self.tableView.layer removeAllAnimations];
[self.tableView setContentOffset:offset animated:NO];

最后,我让tableView处理动画向下滚动,以便单元格的底部位于键盘正上方。

[self.tableView scrollToRowAtIndexPath:CreateNoteCellIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

瞧,它运作得很好。

fixed cell resize

答案 1 :(得分:10)

这是我的UITableView扩展程序完美运行。在Swift 2.1中。根据接受的答案。

extension UITableView
{
    func reloadDataAnimatedKeepingOffset()
    {
        let offset = contentOffset
        UIView.setAnimationsEnabled(false)
        beginUpdates()
        endUpdates()
        UIView.setAnimationsEnabled(true)
        layoutIfNeeded()
        contentOffset = offset
    }
}

答案 2 :(得分:8)

只是一个猜测......

在任何更改之前保存uitableview的contentOffset。然后再设置它。

CGFloat contentOffset = self.tableView.contentOffset;

然后在更改之后

self.tableView.contentOffset = contentOffset;

答案 3 :(得分:4)

更简化的解决方案(在更改textView时添加通知观察器),Swift版本。主要技巧是使用UIView.setAnimationsEnabled

func textViewDidChanged(notification: NSNotification) {
    UIView.setAnimationsEnabled(false)

    let contentOffset = self.tableView.contentOffset

    tableView.beginUpdates()
    tableView.endUpdates()

    tableView.contentOffset = contentOffset

    UIView.setAnimationsEnabled(true)
}