当用户点击我的一行中的按钮时,我正在更新该行的基础模型,然后为给定行调用reloadRowsAtIndexPaths(即单行重新加载)。
- (IBAction)handleCompleteTouchEvent:(UIButton *)sender {
NSIndexPath *indexPath = [self.tableView indexPathForView:sender];
id item = [self dataForIndexPath:indexPath];
if ([item respondsToSelector:@selector(completed)]) {
// toogle completed value
BOOL completed = ![[item valueForKey:@"completed"] boolValue];
[item setValue:[NSNumber numberWithBool:completed] forKey:@"completed"];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
}
问题是,在进行此调用后,表格视图会反弹回到该部分的顶部。如何防止这种情况发生并将滚动位置保持在原位?
答案 0 :(得分:47)
我的所有单元格都有可变高度,所以我在UITableViewDelegate中使用新的iOS7方法,认为它可能会加快渲染时间(不是我真的需要它):
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
无论如何,实现这种方法会产生恶意的副作用,即在调用时使表格反弹到该部分的顶部:
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
为了解决反弹问题,我刚刚删除了estimatedHeightForRowAtIndexPath方法的覆盖,现在一切正常。快乐终于。
答案 1 :(得分:2)
您应该可以通过直接更改单元格内容来执行您要执行的操作。例如,如果您使用的是基础UITableViewCell
类,并且模型中的数据是您在表格视图单元格中显示的NSString
,则可以执行以下操作(更改数据模型后)而不是调用reloadRowsAtIndexPaths
:
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UILabel *label = [cell textLabel];
label.text = @"New Value";
如果您使用的是UITableViewCell的自定义子类,除了访问单元格的视图外,它们大致相同,需要通过contentView属性完成。
答案 2 :(得分:1)
可以将单元格放在它自己的部分并调用重载部分:
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];
这似乎可以部分解决问题。不是最干净的方式,但它可能对你有用。
答案 3 :(得分:1)
在我的类似情况下,我不得不调整方法
的实现- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
...
}
我的身高被重置了。因此,我没有为每个单元格重置高度,而是只更新 reloadRowsAtIndexPaths 调用的受影响单元格。
答案 4 :(得分:1)
Swift 4.2
这可以在您要删除动画的任何地方工作。 在重装表,表节或任何行期间
UIView.performWithoutAnimation({
cell.configureSelection(isSelected: true)
tableView.reloadSections([1], with: .none)
tableView.allowsSelection = false
})
答案 5 :(得分:0)
如果您知道单元格的最小高度,则必须在设置estimatedRowHeight
时指定。我把它设置为1,因为我在某处读过任何高于0的值就足以达到目的,但这是罪魁祸首。
当我将它设置为44,这是我的细胞所能达到的最小高度时,一切都很顺利。
动态高度也很好,没有问题。
答案 6 :(得分:0)
建立xsee的答案 -
我已将界面构建器中的Estimate
设置为"自动"。我将其更改为另一个号码,它开始工作。我保持Row Height
自动。
答案 7 :(得分:0)
我有同样的问题。在更新完我的数据/单元格之后,我最终只是调用tableView.reloadData(),而它并没有反弹回顶部/数据已就地更新-仅供参考
答案 8 :(得分:0)
这帮了我大忙。
UIView.setAnimationsEnabled(false)
tableView.reloadRows(at: [...], with: .none)
UIView.setAnimationsEnabled(true)
答案 9 :(得分:0)
这用 Swift 5 / iOS 14 为我解决了这个问题:
UIView.performWithoutAnimation({
self.tableView.reloadRows(at: [self.idxTouched], with: .none)
})