【问题标题】:White flash when setImageWithUrl displays a cached imagesetImageWithUrl 显示缓存图片时白闪
【发布时间】:2014-05-06 08:04:12
【问题描述】:

使用 AFNetworking 2.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


    【解决方案1】:

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

    在成功块中,替换

    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];
    }
    

    瞧,不再有丑陋的闪光!

    感谢this answer 引导我走上正轨。

    【讨论】:

      【解决方案2】:

      您的问题似乎与单元重用有关,而不是与缓存问题有关。

      当您的单元格被重复使用时(滚动UITableView 或重新打开应用程序时),它们会引用旧图像。当您将nil 传递给placeholderImage 参数时,AFNetworking 不会重置您的图像。这是source code。所以新图像设置在success 块中。但是这个块可能会在轻微的网络延迟后调用,使您的图像闪烁。顺便说一句,您可以省略成功块,以便 AFNetworking 将set the image by itself

      如果您没有 placeHolder 图像,则应在尝试异步设置新图像之前将 myImageView.image 设置为 nil

      此外,您应该检查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;  
      }
      

      【讨论】:

      • 感谢@smnh 如此广泛而快速的回复。不幸的是,这并没有奏效。我用你的代码替换了我的代码,但仍然出现闪烁。不过,您可能已经为我指明了正确的方向。
      • 我尝试设置一个占位符图像以查看行为是否会改变。还是“闪”;在显示缓存图像之前,占位符图像会显示 0.X 秒。我想我可以尝试添加淡入淡出效果。
      • 会不会是你的myImageView.backgroundColor 设置为白色?或者可能在 myImageView 下方有一个白色视图在未设置图像时闪烁?
      • 我的背景确实是白色的。如果对我的解决方案/解决方法感到好奇,请参阅我自己的答案。感谢您的帮助!
      • 您可以将背景设置为透明[UIColor clearColor],这样就不会再出现闪光了。发生这种闪烁的另一个原因是 JPEG 解压缩延迟,因为您使用白色背景和 JPEG 图像作为cellImage
      【解决方案3】:

      你需要这样的函数:

      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);
      }
      

      【讨论】:

        猜你喜欢
        • 2016-02-01
        • 2020-06-01
        • 2015-02-09
        • 2012-05-13
        • 2017-10-22
        • 1970-01-01
        • 2014-10-08
        • 1970-01-01
        • 2016-09-10
        相关资源
        最近更新 更多