当我滚动时,UITableView中的图像会发生变化

时间:2015-03-12 07:33:22

标签: ios uitableview

我试图创建一个像Facebook中的那样的Feed。问题是,后续行上的图像将从初始行加载图像,然后正确加载其相应的加载。当您转到顶行时,先前加载的图像将消失。我尝试过延迟加载,但问题仍然存在。您可以查看视频以更好地了解问题。 (https://www.youtube.com/watch?v=NbgYM-1xYN4

图像是异步加载的,并从我们的服务器中提取。

以下是一些代码:

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    return [latestPosts count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSDictionary * dataDict = [latestPosts objectAtIndex:indexPath.row];

    CardCell *cell = [self.feedTable dequeueReusableCellWithIdentifier:@"CardCell"];
    if (cell == nil) {
        cell = [[CardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CardCell"];
    }
    [cell layoutSubviews];

    NSURL *imageURL = [[NSURL alloc] initWithString:[dataDict objectForKey:@"post_holder_image"]];
    NSURL *postImageURL = [[NSURL alloc] initWithString:[dataDict objectForKey:@"post_image"]];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        NSData *postImageData = [NSData dataWithContentsOfURL:postImageURL];
        dispatch_async(dispatch_get_main_queue(), ^{
            cell.brandImage.image = [UIImage imageWithData:imageData];
            cell.postImage.image = [UIImage imageWithData:postImageData];
        });
    });

    cell.brandName.text = [dataDict objectForKey:@"post_holder"];
    cell.postDateTime.text = [dataDict objectForKey:@"post_datetime"];
    cell.postMessage.text = [dataDict objectForKey:@"post_content"];

    return cell;
}

3 个答案:

答案 0 :(得分:2)

在自定义单元格中使用UITableViewCell的以下方法,并将image属性设置为nil。

希望它对你有用。

-(void)prepareForReuse{
    [super prepareForReuse];

    // Then Reset here back to default values that you want.
}

答案 1 :(得分:1)

上面有一些问题。

如上所述,您需要在单元初始化代码和单元重用中使用图像作为占位符(即空白或您选择的图像)。

您确实需要缓存图像,只需下载一次图像,然后将其存储在字典中。即:

            UIImage *cachedImage = self.images[user[@"username"]];
            if (cachedImage) {
                //use cached image
                [button setBackgroundImage:cachedImage forState:UIControlStateNormal];
            }

            else {

                //download image and then add it to the dictionary }

其中self.imagesNSMutableDictionary。您还可以查看NSCache。如果你不缓存图像,你会发现由于从数据中转换图像而滚动大量行时表格非常滞后。

但是,如果您开始加载表格并快速向上和向下滚动图像将显示在错误的位置并移动直到它们全部加载,这将无法完全解决问题。细胞重用会混淆图像的放置位置。确保将[tableView reloadItemsAtIndexPaths:@[indexPath]];放入下载区,即:

NSURL *imageURL = [[NSURL alloc] initWithString:[dataDict objectForKey:@"post_holder_image"]];
    NSURL *postImageURL = [[NSURL alloc] initWithString:[dataDict objectForKey:@"post_image"]];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        NSData *postImageData = [NSData dataWithContentsOfURL:postImageURL];
        dispatch_async(dispatch_get_main_queue(), ^{
            cell.brandImage.image = [UIImage imageWithData:imageData];
            cell.postImage.image = [UIImage imageWithData:postImageData];
            [tableView reloadItemsAtIndexPaths:@[indexPath]];
        });
    });

答案 2 :(得分:0)

您需要将imageview.image设置为nil,否则应在重复使用单元格时设置占位符图像。这是同一个问题Async image loading from url inside a UITableView cell - image changes to wrong image while scrolling 除此之外,如果你没有使用parse.com api ect。您可以查看https://github.com/rs/SDWebImagehttps://github.com/AFNetworking/AFNetworking 关于这个话题有很多答案。

[cell layoutSubviews];
cell.brandImage.image = nil;
cell.postImage.image = nil;