调用reloadRowsAtIndexPaths会删除tableView contentOffset [英] Calling reloadRowsAtIndexPaths removes tableView contentOffset

查看:109
本文介绍了调用reloadRowsAtIndexPaths会删除tableView contentOffset的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我打电话

reloadRowsAtIndexPaths

我的UITableView contentOffset已被删除,是否有一个委托方法我可以用来捕获表视图更新并再次设置Offset以使其保持原位并且不会动画到视图中,或者只是阻止它这样做?

My UITableView contentOffset is removed, is there a delegate method I can use to catch the table view updating and set the Offset again so that it remains in place and does not animate into view, or simply prevent it doing this?

我在viewDidLoad中设置contentOffest:

I am setting the contentOffest in viewDidLoad:

self.tableView.contentOffset = CGPointMake(0, 43);

以下是一个示例用法:

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[params valueForKey:@"index"], nil] withRowAnimation:UITableViewRowAnimationFade];

删除contentOffset并将其设置为视图,这是我不想要的。

Which removes the contentOffset and animates it into view, which I do not want.

更具体地说,当重新加载的行位于indexPath.section 0和indexPath.row 0(即顶行)时,会出现这种情况。

More specifically this appears to occur when the row being reloaded is at indexPath.section 0 and indexPath.row 0, i.e. the top row.

更多信息

我在获取图片的异步请求后调用reloadRowsAtIndexPaths从服务器。它基本上是这样的:

I am calling reloadRowsAtIndexPaths after an asynchronous request to fetch an image from a server. It basically works like so:


  • 调用cellForRowAtIndexPath,检查磁盘上是否存在拇指文件,如果文件不存在占位符被加载到它的位置,异步请求在后台线程中启动以获取图像。

  • 当图像下载完成后,我调用 reloadRowsAtIndexPaths 表示正确的单元格,以便正确的图像淡入而不是占位符图像。

  • 在cellForRowAtIndexPath中调用请求时,单元格的数量可能不同,因此图像加载时单元格加载

  • cellForRowAtIndexPath is called which checks for the presence of the thumb file on the disk, if the file is not present a placeholder is loaded in it's place and an asynchronous request is started in a background thread to fetch the image.
  • When the image download has completed I call reloadRowsAtIndexPaths for the correct cell so that the correct image fades in in place of the placeholder image.
  • The amount of cells may be different as the request is called inside cellForRowAtIndexPath so that the images load in as the cells load

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;
    }

}


推荐答案

编辑:我的原始答案可能没有关注核心问题

您是否在调用 reloadRows ... 之前更改了行数? reloadRows ... 专门用于设置值更改的动画,因此您的代码应如下所示:

Are you changing your number of rows before the call to reloadRows...? reloadRows... is specifically to animate a value change, so your code should look something like this:

UICell *cell = [self cellForRowAtIndexPath:indexPath];
cell.label.text = @"Something new";
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]];

这或多或少是你的样子,但是tableview却忘记了它的位置?

Is that more or less what you look like, but the tableview is forgetting where it is?

上一个讨论

你不要重新加载时不要调用 -beginUpdates -endUpdates 。您可以在支持数据的相关修改周围调用 -beginUpdates -endUpdates ,在此期间您应该调用 -insertRowsAtIndexPaths:withRowAnimation:及其亲属。如果调用更新例程,则无需调用重新加载例程。在更新过程中重新加载是未定义的行为。

You don't call -beginUpdates and -endUpdates around a reload. You call -beginUpdates and -endUpdates around your related modifications of the backing data, during which you should be calling -insertRowsAtIndexPaths:withRowAnimation: and its relatives. If you call the updating routines, then you don't need to call the reload routines. Reloading in the middle of an update is undefined behavior.

参见批量插入,删除和重新加载行和节,以获取有关何时使用 -beginUpdates

See Batch Insertion, Deletion, and Reloading of Rows and Sections for details on when you use -beginUpdates.

这篇关于调用reloadRowsAtIndexPaths会删除tableView contentOffset的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆