如何在延迟一段时间后在tableView中加载图像?

时间:2011-04-09 04:16:30

标签: iphone objective-c cocoa-touch uitableview ios4

我见过一个名为ZuluTrade的应用程序,它在tableView单元格中有一个图表。

基本上它似乎是tableViewCell的imageView中的图像。

当页面加载时,tableView首先显示文本然后在我们滚动tableView时将图像加载到tableViewCell中。

这有助于提高性能,因为用户不必等到所有内容都加载到单元格中,并且还使tableView滚动平滑。

如何实现这一功能?

以下是应用的截图:

enter image description here

enter image description here

我的tableView中的代码cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

NSString *MyIdentifier = [NSString stringWithFormat:@"MyIdentifier %i", indexPath.row];

MyTableCell *cell = (MyTableCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
//if (cell == nil) {
    cell = [[[MyTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];


    NSString *testVal = [[NSUserDefaults alloc] valueForKey:@"idValue"];

    if (testVal == (NSString *)[NSNull null]) {
        testVal = @"NULL";
    }
    //NSLog(@"testVal : %@",testVal);
NSLog(@"Fund Name : %@",[[array1 objectAtIndex:indexPath.row] valueForKey:@"FundName"]);

    NSDate *date = [NSDate date];
NSDateFormatter *dtFormat = [[NSDateFormatter alloc] init];
[dtFormat setDateFormat:@"yyyy-MM-dd"];
NSString *dtString = [dtFormat stringFromDate:date];

  NSString *fundname = [NSString stringWithFormat:@"%@",[[array1 objectAtIndex:indexPath.row] valueForKey:@"FundName"]];


NSString *imageName =[NSString stringWithFormat:@"%@_%@.png",fundname,dtString]; 
//NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsDirectory = [self getImagePath];
NSLog(@"Image Path : %@",documentsDirectory);
NSError *error1;
NSString *filepath1;
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:&error1];
if (files == nil) {
    NSLog(@"Error reading contents of documents directory: %@", [error1 localizedDescription]);
}
NSLog(@"FileName: %@",imageName);
BOOL success = NO;
for (NSString *file in files)
{
    NSLog(@"file in Files is %@",file);
    if([file isEqualToString:[NSString stringWithFormat:@"%@",imageName]])
    {
        filepath1 = [documentsDirectory stringByAppendingPathComponent:file];
        NSLog(@"Full Path :%@",filepath1);
        success = YES;
    }
}




    if(success == YES)
    {
        cell.imageView.image = [UIImage imageWithContentsOfFile:filepath1];
    }
    else if(success != YES)
    {
        cell.imageView.image = [UIImage imageNamed:@"newfund.png"];
    }


    UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(60.0, 0, 120.0, 
                                                                tableView.rowHeight)] autorelease]; 
    [cell addColumn:50];
    label.textColor = [UIColor blackColor];
    label.tag = LABEL_TAG; 
    label.font = [UIFont systemFontOfSize:12.0]; 
    //NSLog(@"%@",[[array1 objectAtIndex:indexPath.row] valueForKey:@"FundName"]);
    label.text = [NSString stringWithFormat:@"%@",[[array1 objectAtIndex:indexPath.row] valueForKey:@"FundName"]];
    //NSLog(@"FundName: %@",label.text);
    label.textAlignment = UITextAlignmentCenter; 
    //label.textColor = [UIColor blueColor]; 
    label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | 
    UIViewAutoresizingFlexibleHeight; 
    [cell.contentView addSubview:label];        

return cell;
}

5 个答案:

答案 0 :(得分:3)

您可以从文档目录添加图像,并将它们作为Lazy表图像添加到表视图中。

为此您可以使用以下

查看下面的SDWebImage存储库链接。

https://github.com/rs/SDWebImage#readme

这会帮助你。

现在你需要做一个小改动:

[cell.imageView setImageWithURL:[NSURL fileURLWithPath:test1.png]
           placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

取代

[cell.imageView setImageWithURL:[NSURL URLWithString:test1.png]
           placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

乐意帮助: - )

答案 1 :(得分:2)

tableView:cellForRowAtIndexPath:中配置单元格时,应检查是否加载了图像(如果是这样的话 - 从那里显示)。

当加载图像(全部或部分图像)时,应该调用表视图的reloadData / reloadRowsAtIndexPaths:withRowAnimation: / reloadSections:withRowAnimation:)以从缓存中删除旧生成的表格单元格

更新:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        UIImageView *imgView = [[[UIImageView alloc] init] autorelease];
        imgView.hidden = YES;
        imgView.tag = 5555;
        [cell addSubview:imgView];
    }

    if (nil != _images[indexPath.row]) {
        UIImageView *imgView = (UIImageView *)[cell viewWithTag:5555];
        imgView.image = _images[indexPath.row];
        [imgView sizeToFit];
        imgView.hidden = NO;
    }

    return cell;
}

这里的_images []是带有单元格图像的容器(UIImage指针)。我想在这个例子中我们只有一个部分让我自己使用一些简单的容器。如果未加载图像,则_images []存储nil,否则为必需的UIImage *。

在一些在图像加载时调用的方法中,您应该执行以下步骤:

  1. 保存相应_images []索引的图像。

  2. 调用tableView的reloadRowsAtIndexPaths:withRowAnimation:以获取必要的部分&行(当然来自主线程)。

答案 2 :(得分:1)

一种方法可能是,当您加载单元格时,您可以启动一个新线程来加载图像。

[NSThread detachNewThreadSelector:@selector(loadData:) toTarget:self withObject:nil];

然后在同一个班级中,您需要使用该方法进行工作和回电。

-(void) loadData:(id)object
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    //do stuff here
    [pool release];
    //Call back
    [self performSelectorOnMainThread:@selector(loadDataComplete:) withObject:nil waitUntilDone:NO];
}


-(void) loadDataComplete:(id)object
{
    // Maybe be more clever and pass the indexPath around so you can just load that row.
    [tableView reloadData]; 
}

答案 3 :(得分:1)

当单元格首次可见时,调用方法tablView:cellForRowAtIndexPath:以显示文本。将单元格标记为可见。使用异步线程(子类NSOperation)加载图像。当映像为特定单元准备就绪时,将–reloadRowsAtIndexPaths:withRowAnimation:发送到表视图以从并发线程加载该特定行。我不会使用reloadData,因为这会导致重新加载表中的所有数据,并可能影响滚动性能。

答案 4 :(得分:0)

结帐LazyTableImages sample code by Apple

  

此示例演示了一种多阶段加载方法   显示UITableView。首先从加载相关文本   一个RSS提要,以便表格可以尽快加载,然后   以异步方式下载每行的图像,以便UI更多   响应。