11

I'm been using SDWebImage(ver3.0) on my iOS app, and I want to fade in the new image of uitableviewcell once it loads like Path2.0, Pinterest, and Viddy.Thanks to iOS SDWebImage fade in new image, fade-in itself is working. However, image in cell is loaded again when scrolling tableview. This may be caused by a reuse of a cell.

Here is my code.

[cell.userImageView setImageWithURL:url
                   placeholderImage:placeholderImage
                          completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
                              if (!error) {
                                  cell.userImageView.alpha = 0.0;
                                  [UIView transitionWithView:cell.userImageView
                                                    duration:1.0
                                                     options:UIViewAnimationOptionTransitionCrossDissolve
                                                  animations:^{
                                                      [cell.userImageView setImage:image];
                                                      cell.userImageView.alpha = 1.0;
                                                  } completion:NULL];
                              }
                          }];
Community
  • 1
  • 1
tsk
  • 225
  • 3
  • 9
  • Find out if SDWebImage does caching - if so, make sure you only animate non cached loads. – Till Dec 25 '12 at 17:53
  • Thanks! Caching is done. But, I did not check I only animate non cached loads... – tsk Dec 25 '12 at 19:25
  • Possible duplicate of [iOS SDWebImage fade in new image](https://stackoverflow.com/questions/11869390/ios-sdwebimage-fade-in-new-image) – ray Jul 31 '18 at 17:41

1 Answers1

25

Credit goes to @OzBoz for pointing out that the correct solution is to just confirm whether the image was retrieved from the network (not cached) and if so, perform the animation:

[cell.userImageView setImageWithURL:url
                   placeholderImage:placeholderImage
                          completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
                              if (image && cacheType == SDImageCacheTypeNone)
                              {
                                  cell.userImageView.alpha = 0.0;
                                  [UIView animateWithDuration:1.0
                                                   animations:^{
                                                       cell.userImageView.alpha = 1.0;
                                                   }];
                              }
                          }];

If you're concerned about the cell no longer being visible), you can also use:

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

This method (not to be confused by the similarly named UITableViewDataSource method) will return non-nil if the row is still visible. This is very important to do in most UITableViewCell async image retrieval processes, but it turns out that setImageWithURL will cancel any prior image retrieval processes, so it's less critical to check this when using SDImageWeb.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks!!Your code works well(I replaced the UITableViewCell type with my custom cell subclass)!! I didn't know I should check to see if a cell is still visible when asynchronous updating the cell. So, I learned a lot. – tsk Dec 25 '12 at 19:07
  • @Rob I'm just curious, I was using if (cacheType == SDImageCacheTypeNone) instead of UITableView *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell) for one time showing animation after loading data from http. After I use your if statement, I could not figure out why cell comes as zero if the image in cell cashed before. – OzBoz Mar 11 '13 at 00:09
  • @Rob Thanks for the answer. But, still something is not clear. Logic behind of using 'cacheType == SDImageCacheTypeNone' to check if the data comes from web then make animation. If not, then do not because cached image should immediately shown without animation (like instagram app). The thing I could not understand is why cell become nil (Reused by another row) if the setting image to imageview is pre-loaded. If I change the link of image in the second row, cell become non-zero. Why is this like that? – OzBoz Mar 11 '13 at 11:29
  • @Rob Moreover,`[cell.userImageView setImage:image];` is also redundant. Because after image downloaded, SDWebImage handled setting the image already itself. – OzBoz Mar 11 '13 at 11:30
  • 1
    @OzBoz You are quite right that if you want to check to see if you're asynchronously retrieving image from the web (and thus need animation) that you should just check `if (cacheType == SDImageCacheTypeNone) ...`. I've updated my answer accordingly. My prior answer about `cellForRowAtIndexPath` is only critical if you're asynchronously retrieving an image and the cell has subsequently scrolled off before the async image retrieval is done. But it turns out that `SDWebImage`, when called on a reused cell, will cancel previously queued network operations, so this is of negligible concern. – Rob Mar 11 '13 at 21:50
  • It makes UITable view scrolling jerky also when I push to table view from another view controller, slight lagging was there. How can I resolve this ? – Sushil Sharma Feb 01 '16 at 13:07