UITableView在单元格刷新上滚动到顶部

我有一个单元格的UITableViewdynamicresize,以适应其中的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 } 

}

resize和表格边界是预期的。 但是,不仅仅是animation高度的变化,它也滚动到顶部。 这可以在这里看到,当按下返回键。

表格滚动的单元格大小

通过关键值观察,我发现当滚动视图的contentSize改变时,滚动视图contentOffset被设置。 并且在调用endUpdates方法时contentSize会多次改变。 当它发生变化时,它会从正常的高度变成相当大的高度,然后回到正常的高度。 我想知道是否会因为这个而上榜。 我不知道该从哪里出发。

哇,Josh Gafni的回答很有帮助, 他值得高兴。 我的解决scheme是基于他的。 这仍然感觉像一个黑客,所以如果有人还有更好的办法做到这一点,我仍然很有兴趣听到它。

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

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

这激活了单元格的高度变化,并调整所有框架以适应约束条件。

接下来,我从tableView的图层中删除所有的animation,所以顶部的animation停止。 然后,我重置contentOffst到以前。

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

最后,我让tableView处理animation向下滚动,这样单元格的底部就在键盘的正上方。

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

瞧,它工作得很好。

固定的单元格大小

只是一个猜测…

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

 CGFloat contentOffset = self.tableView.contentOffset; 

然后在变化之后

 self.tableView.contentOffset = contentOffset; 

这是我的UITableView扩展,完美的作品。 在Swift 2.1中。 基于接受的答案。

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

更简化的解决scheme(当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) }