每当我打电话
reloadRowsAtIndexPaths
我的UITableView contentOffset已删除,是否有一个委托方法,我可以使用它来捕获表视图更新并再次设置Offset以使其保持原位并且不会动画显示到视图中,或者只是阻止它执行此操作?
我在viewDidLoad中设置contentOffest:
self.tableView.contentOffset = CGPointMake(0, 43);
以下是一个示例用法:
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[params valueForKey:@"index"], nil] withRowAnimation:UITableViewRowAnimationFade];
删除contentOffset并将其设置为视图,这是我不想要的。
更具体地说,当重新加载的行位于indexPath.section 0和indexPath.row 0(即顶行)时,会出现这种情况。
更多信息
我在从服务器获取图像的异步请求之后调用reloadRowsAtIndexPaths。它基本上是这样的:
reloadRowsAtIndexPaths
,以便正确的图像淡入而不是占位符图像。cellForRowAtIndexPath文件检查
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_small.gif",[[listItems objectAtIndex:indexPath.row] valueForKey:@"slug"]]];
if([[NSFileManager defaultManager] fileExistsAtPath:path]){
listCell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:path]];
} else {
listCell.imageView.image = [UIImage imageNamed:@"small_placeholder.gif"];
NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[[[listItems objectAtIndex:indexPath.row] valueForKey:@"image"] valueForKey:@"small"],@"image",[NSString stringWithFormat:@"%@_small.gif",[[listItems objectAtIndex:indexPath.row] valueForKey:@"slug"]], @"name",indexPath,@"index",@"listFileComplete",@"notification",nil];
[NSThread detachNewThreadSelector:@selector(loadImages:) toTarget:self withObject:params];
[params release];
}
文件已下载通知:
-(void)fileComplete:(NSNotification *)notification {
[self performSelectorOnMainThread:@selector(reloadMainThread:) withObject:[notification userInfo] waitUntilDone:NO];
}
单元格重新加载(我有一些硬编码的部分,因为奇怪的部分编号被传递的错误很少导致崩溃:
-(void)reloadMainThread:(NSDictionary *)params {
NSIndexPath *index;
switch ([[params valueForKey:@"index"] section]) {
case 0:
index = [NSIndexPath indexPathForRow:[[params valueForKey:@"index"] row] inSection:0];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[params valueForKey:@"index"], nil] withRowAnimation:UITableViewRowAnimationNone];
break;
default:
index = [NSIndexPath indexPathForRow:[[params valueForKey:@"index"] row] inSection:2];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:index,nil] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
答案 0 :(得分:3)
编辑:我原来的答案可能没有关注核心问题
您是否在调用reloadRows...
之前更改了行数? reloadRows...
专门用于设置值更改的动画,因此您的代码应如下所示:
UICell *cell = [self cellForRowAtIndexPath:indexPath];
cell.label.text = @"Something new";
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]];
这或多或少是你的样子,但是tableview却忘记了它的位置?
之前的讨论
您不会在重新加载时调用-beginUpdates
和-endUpdates
。您可以围绕对支持数据的相关修改调用-beginUpdates
和-endUpdates
,在此期间您应该调用-insertRowsAtIndexPaths:withRowAnimation:
及其亲属。如果调用更新例程,则无需调用重新加载例程。在更新过程中重新加载是未定义的行为。
有关何时使用-beginUpdates
的详细信息,请参阅Batch Insertion, Deletion, and Reloading of Rows and Sections。
答案 1 :(得分:3)
由于错误估计的行高,听起来像是遇到了这个问题。因为(出于一些神秘的原因)表视图在使用估计的行高重新加载某些单元格后确定新的偏移量,您要确保tableView:estimatedHeightForRowAtIndexPath
为已经存在的单元格返回正确的数据渲染。要实现此目的,您可以在字典中缓存看到的行高:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
heightForIndexPath[indexPath] = cell.frame.height
}
然后使用这个正确的数据或估计未加载的单元格:
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return heightForIndexPath[indexPath] ?? averageRowHeight
}
(非常感谢eyuelt的洞察力,估计行高用于确定新的偏移量。)
答案 2 :(得分:0)
您是否尝试过以下操作:
CGPoint offset = [self.tableView contentOffset];
CGSize size = [self.tableView contentSize];
CGFloat percentScrolled = offset.y / size.height;
// call reloadRowsAtIndexPaths, inserts, deletes etc.
// ...
CGSize newSize = [self.tableView contentSize];
CGSize newOffset = CGPointMake(0, newSize.height * percentScrolled);
[self.tableView setContentOffset:newOffset animated:NO];
这似乎有点过于微不足道,不确定它会起作用,但值得一试。
答案 3 :(得分:0)
替换
[_tableView reloadData];
与
[_tableView reloadRowsAtIndexPaths:...withRowAnimation:...];
它会很好。
答案 4 :(得分:0)
我用这个:
-(void)keepTableviewContentOffSetCell:(cellClass *)cell{
CGRect rect = cell.frame;
self.tableView.estimatedRowHeight = rect.size.height ;
}
您可以在重新加载单元格之前使用它。重新加载单元格时,表格视图不会滚动。