当setImageWithUrl显示缓存图片时,会有白色闪光。

问题描述 投票:1回答:3

使用AFNetworking2.0的方法setImageWithUrl,我在位于UITableViewCell中的imageView中设置了一张图片。当显示的图像第一次被下载,然后设置时,它工作得很好。但是,如果在设置时,图片在本地可用(已被缓存),则在显示之前会有快速的白闪。

你知道如何避免这种情况吗?

重现的步骤。

  1. 设置图像(图像将被缓存)
  2. 关闭申请
  3. 开始申请
  4. 设置(现在缓存的)图像

设置图像的代码。

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

    myCell *cell = (myCell *)[tableView dequeueReusableCellWithIdentifier:@"imageCell"];

    [cell.myImageView setImageWithURLRequest:[NSURLRequest requestWithURL:myImageUrl] placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
        cell.myImageView.image = image;

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
        NSLog(@"Failed");
    }];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;  
}
ios image caching afnetworking afnetworking-2
3个回答
8
投票

如果有人碰到同样的问题,我是这样解决的。

在成功区块中,替换

cell.myImageView.image = image;

if (request) {
    [UIView transitionWithView:cell.myImageView
                      duration:0.8f
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{[cell.myImageView setImage:image];}
                    completion:NULL];
}else{
    [cell.myImageView setImageWithURL:myImageURL];
}

瞧,再也没有丑陋的闪光了!

归功于 本回答 感谢你把我引向正确的方向。


0
投票

看来您的问题是与单元格重用有关,而不是与缓存问题有关。

当您的单元格被重用时(当滚动的时候)。UITableView 或重新打开应用程序)它们持有对旧图像的引用。而当你通过 nilplaceholderImage 参数,AFNetworking不会重置您的图像。这里是 源码. 所以新的图像设置在 success 块。但是这个块可能会在轻微的网络延迟后被调用,使你的图像闪光。顺便说一下,你可以省略成功块,这样AFNetworking就会被调用。独树一帜.

如果你没有placeHolder图像,你应该设置 myImageView.imagenil 在试图异步设置一个新的之前。

此外,您应该检查 dequeueReusableCellWithIdentifier: 方法返回一个单元格,如果没有,则创建一个新的单元格。这可能发生在 UITableView 是第一次创建。

下面是一个例子。

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

    myCell *cell = (myCell *)[tableView dequeueReusableCellWithIdentifier:@"imageCell"];

    // Check if reused cell was returned.
    // If not create a new one, otherwise, reset the state of the reused cell
    if (!cell) {
        cell = [[myCell alloc] init];
    } else {
        cell.myImageView.image = nil;
    }

    [cell.myImageView
        setImageWithURLRequest:[NSURLRequest requestWithURL:myImageUrl]
        placeholderImage:nil
        success:nil
        failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
            NSLog(@"Failed");
        }];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;  
}

0
投票

你需要一个这样的函数

BOOL ImageDataHasPNGPreffix(NSData *data) {
NSUInteger pngSignatureLength = [kPNGSignatureData length];
if ([data length] >= pngSignatureLength) {
    if ([[data subdataWithRange:NSMakeRange(0, pngSignatureLength)] isEqualToData:kPNGSignatureData]) {
        return YES;
    }
}

return NO;
}

然后当你保存数据时,你需要选择正确的方式来缓存。

//Saving data
if ([imageData length] >= [kPNGSignatureData length]) {
    imageIsPng = ImageDataHasPNGPreffix(imageData);
}

if (imageIsPng) {
    data = UIImagePNGRepresentation(image);
}
else {
    data = UIImageJPEGRepresentation(image, (CGFloat)1.0);
}
© www.soinside.com 2019 - 2024. All rights reserved.