UITableView在滚动时更改图像

时间:2013-09-23 16:13:20

标签: ios objective-c uitableview uiimage

每次滚动TableView时,我的图像都会混乱,主要是第一行。我真的不知道该做什么。

以下是代码:

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

    BarCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    [cell.activityFotoBar startAnimating];
    cell.activityFotoBar.hidesWhenStopped = YES;

   if(!cell){
       cell = [[BarCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
   }

    NSMutableDictionary *infoBar = [self.bares objectAtIndex:indexPath.row];
    NSString *nomeImagem = [infoBar objectForKey:@"foto"];

    NSURL *url = [NSURL URLWithString:nomeImagem];
    NSURLRequest *requestImagem = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:requestImagem queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        if(connectionError == nil){
            cell.imageViewImagemBar.image = [UIImage imageWithData:data];
            [cell.activityFotoBar stopAnimating];
        }

    }];


    cell.labelNomeBar.text = [infoBar objectForKey:@"nome"];
    cell.labelEnderecoBar.text = [infoBar objectForKey:@"endereco"];
    cell.labelAvaliacaoBar.text = [NSString stringWithFormat:@"Votos: %@", [infoBar objectForKey:@"votos"]];

    return cell;

}

提前致谢!

3 个答案:

答案 0 :(得分:1)

问题出现是因为异步图像请求在您的单元格滚出屏幕并重新使用后完成。下载完成"故障",导致视觉混乱。从本质上讲,一些通过滚动重新使用的单元仍然是热的",在它们的图像负载正在进行的意义上。重复使用此类单元格会在旧图像和新图像下载之间产生竞争。

您应该更改用于加载图片的策略:而不是发送请求并且"忘记"它,考虑使用connectionWithRequest:delegate:方法,将连接存储在单元格中,并在调用cancel方法时调用prepareForReuse。通过这种方式,您重复使用的单元格将会冷却#34;

答案 1 :(得分:0)

您可以使用SDWebcache库。它包含一个UIImageView类别类,可以从URL加载图像。我觉得它适用于tableviews

答案 2 :(得分:0)

代码应“几乎”有效。你只需要解决一个问题就可以使它工作(虽然不是最佳):

异步请求sendAsynchronousRequest:queue:completionHandler:完成后,将调用完成处理程序。然后,您需要从表视图中再次检索单元格,并在请求启动时指定 indexPath

您只需要捕获块中的 indexPath ,以便获得一个在块完成之前保持有效的引用。

UITableView检索单元格的方法是

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath

如果返回值(单元格)为nil,则索引路径 indexPath 处的单元格不可见。

因此,完成块将如下所示:

    if (error == nil && ... ) {
        BarCell* cell = [self.tableView cellForRowAtIndexPath:indexPath]
        if (cell) {
            cell.imageViewImagemBar.image = [UIImage imageWithData:data];
            [cell.activityFotoBar stopAnimating];
        }
    }

这也安全地处理了单元格为零的情况。

注意:虽然这个“有效”,但它仍然是一种天真的做法。更复杂的方法可以缓存(解码的)图像,并可能有一些“向前看和急切的驱逐策略”,以获得更好的用户体验和更低的内存占用。

请注意,imageWithData:可能仍然很昂贵,因为可能需要在呈现图像之前对图像进行解码,解压缩和调整大小。基本上,这可以预先执行,具有屏幕外的上下文。