在UITableView中延迟加载图像

时间:2009-07-15 08:21:52

标签: iphone ios objective-c uitableview

我的UITableView中有大约50个自定义单元格。我想在单元格中显示图像和标签,我从URL中获取图像。

我想要延迟加载图像,以便在加载图像时UI不会冻结。我尝试在单独的线程中获取图像,但每次单元格再次可见时我必须加载每个图像(否则重复使用单元格会显示旧图像)。有人可以告诉我如何复制这种行为。

8 个答案:

答案 0 :(得分:17)

尝试 AFNetworking 课程在此链接https://github.com/AFNetworking/AFNetworking下载此课程。在项目中添加所有AFNetworking类。然后只导入此类别

#import "UIImageView+AFNetworking.h" in your Viewcontroller which contains your Tableview.

然后在 cellForRowAtIndexPath:中添加如下

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

    if (cell == nil) 
    {
        cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }

    [cell.imageView setImageWithURL:[NSURL URLWithString:[UrlArray objectAtIndex:indexPath.row]] placeholderImage:[UIImage imageNamed:@"placeholder.jpg"]];
     cell.myLabel.text = [imageNameArray objectAtIndex:indexPath.row];

     cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;    
}

以异步方式下载 UITableviewcell 中的imageView图像。当用户滚动Tableview时,它不会一次又一次地下载,因为它也有缓存。下载图像后,使用imageUrl的密钥保存图像。我希望它对你有用。

答案 1 :(得分:3)

我建议你去寻找NSOperation并在另一个线程上做你需要的任何事情。

这是我为图片加载而写的课程:

- (id)initWithTarget:(id)trgt selector:(SEL)sel withImgURL:(NSString *)url {
    if(self = [super init]) {
        if(url == nil || [url isEqualToString:@""])
            return nil;
        target = trgt;
        action = sel;
        imgURL = [[NSURL alloc] initWithString: url];
    }
    return self;
}

- (void)main {
    [NSThread detachNewThreadSelector:@selector(loadImage) toTarget:self withObject:nil];
}

- (void)loadImage {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    UIImage *img = [UIImage imageNamed: @"default_user.png"];
    if(![[imgURL absoluteString] isEqualToString: @"0"]) {
        NSData *imgData = [NSData dataWithContentsOfURL: imgURL];
        img = [UIImage imageWithData: imgData];
    }
    if([target respondsToSelector: action])
        [target performSelectorOnMainThread: action withObject: img waitUntilDone: YES];
    [pool release];
}

- (void)dealloc {
    [imgURL release];
    [super dealloc];
}

希望有所帮助!

答案 2 :(得分:2)

你可以使用自我图像按钮..你可以从github下载自我图像按钮文件...添加你的项目....

在xib中的图像视图中更改“自我图像按钮”类...

延迟加载称为同步请求..

自我图像称为异步请求。自我形象不要等待回应..一次显示所有图像..

答案 3 :(得分:1)

也许你可以尝试ALImageView。它比SDWebImage简单得多。你只需要两个源文件( ALImageView.h / ALImageView.m )。你可以重用图像查看以在tableview单元格中重新加载不同的URL。

  1. 支持本地和内存缓存;
  2. 支持占位符;
  3. 支持点击触摸(目标操作);
  4. 支持图像视图的角落;
  5. 还有一个很好的演示。

答案 4 :(得分:1)

你可以尝试这个lazyTableImages


我已经将这个项目的lazyTableImages定制为一个非常简单的(customizeLazyTableImages),并删除了所有额外的代码和一些静态网址和标题,这只是非常顺利地加载图像并缓存它们


答案 5 :(得分:0)

我认为如果你想在视图的开头加载那个图像,还有另一种方法可以解决这个问题

加载-(void)loadView时,只需分配这些图片,然后在加载表格单元格时将其带入nsarray,然后根据indexPath.row在表格单元格中进行查看只需将nsarray的这些图像替换为该视图作为背景图像,或者使用tableview单元格的nsarray索引和indexPath.row在表格单元的新视图上制作这些图像的子视图。

答案 6 :(得分:0)

您可以使用NSOperation队列或GCD在后台加载图像。

如果您不想反复加载图像,可以使用NSCache或文件系统存储图像。

答案 7 :(得分:-1)

我不知道有任何内置的方法来实现这一点,但听起来你已经有了一些与另一个线程合作的东西。

假设您现在唯一剩下的问题是当单元格返回视图时使其内容无效,您应该查看:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

通过实现此委托方法,您可以在绘制之前检查单元格的内容,以查看它是否需要新内容。如果是,那么你可以清空单元格内容并再次触发线程加载。

您也可以考虑发布一些代码。