UIImageView+AFNetworking setImageWithURL with animation

27,146

Solution 1

You can use animateWithDuration in conjunction with the rendition of setImageWithURL that supplies the success block, e.g.

[imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] 
          placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]
                   success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                       self.imageView.alpha = 0.0;
                       self.imageView.image = image;
                       [UIView animateWithDuration:0.25
                                        animations:^{
                                            self.imageView.alpha = 1.0;
                                        }];
                   }
                   failure:NULL];

Or, if you placeholder image isn't blank, you would probably want to cross dissolve via transitionWithView:

[imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] 
          placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]
                   success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                       [UIView transitionWithView:self.imageView
                                         duration:0.3
                                          options:UIViewAnimationOptionTransitionCrossDissolve
                                       animations:^{
                                           self.imageView.image = image;
                                       }
                                       completion:NULL];
                   }
                   failure:NULL];

Update:

By the way, if you're concerned about the fact that the image view (and if you refer to self, the view or the view controller, too) being retained until the download is done, you could:

__weak UIImageView *weakImageView = self.imageView;
[imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] 
          placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]
                   success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                       UIImageView *strongImageView = weakImageView; // make local strong reference to protect against race conditions
                       if (!strongImageView) return;

                       [UIView transitionWithView:strongImageView
                                         duration:0.3
                                          options:UIViewAnimationOptionTransitionCrossDissolve
                                       animations:^{
                                           strongImageView.image = image;
                                       }
                                       completion:NULL];
                   }
                   failure:NULL];

Even if you do that, the image view is retained until the download completes, so you could optionally also cancel any download in progress in the dealloc method of the view controller:

- (void)dealloc
{
    // if MRC, call [super dealloc], too

    [_imageView cancelImageRequestOperation];
}

Solution 2

Try animating the alpha of the imageView from 0 to 1 when the online request completes with success:

// You should not call an ivar from a block (so get a weak reference to the imageView)
__weak UIImageView *weakImageView = self.imageView;

// The AFNetworking method to call
[imageView setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://host.com/image1.png"]] placeholderImage:nil] 
                   success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){ 
                     // Here you can animate the alpha of the imageview from 0.0 to 1.0 in 0.3 seconds
                     [weakImageView setAlpha:0.0];
                     [UIView beginAnimations:nil context:NULL];
                     [UIView setAnimationDuration:0.3];
                     [weakImageView setAlpha:1.0];
                     [UIView commitAnimations];
                   }
                   failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
                     // Your failure handle code     
                   }

Of course you can use any other animation you like inside the completion block!

Share:
27,146

Related videos on Youtube

Daniel Campos
Author by

Daniel Campos

Updated on July 19, 2020

Comments

  • Daniel Campos
    Daniel Campos almost 4 years

    With AFNetworking, is very simple to download an image from a server and put into an UIImageView:

    [imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]];
    

    How about if I want to do this replacement of image with an effect (maybe fade)???

    It's because I want to make a slideshow with a lot of images.

  • Marcelo
    Marcelo almost 11 years
    Be careful with retain cycles, though.
  • timpone
    timpone almost 11 years
    @MarceloFabri could you elaborate. Which retain cycle?
  • Daniel Campos
    Daniel Campos almost 11 years
    Rob, do you know if is possible to make a Fade effect for loading. I mean: 0% loaded = opacity 0.0, 100% loaded - opacity 1.0
  • Rob
    Rob almost 11 years
    @timpone This will, indeed, retain the image view (and if you refer to self, the controller, too) for the duration of the download. I wouldn't call it a retain cycle, though, because when it's done, the circular reference is resolved and everything is released. Unfortunately, AFNetworking will retain the image view during the download retrieval, regardless, so the usual trick of weak references won't solve this issue. You just have to live with "retain during download" behavior, or go to a more robust UIImageView category. Personally I wouldn't sweat it.
  • Rob
    Rob almost 11 years
    @DanielCampos Short answer: not really. Long answer: Two problems with that idea. First, the UIImageView category doesn't provide a progress block, so you'd have to resort to AFImageRequestOperation (in which you lose some great UIImageView category benefits). Worse, even if you did a lot of work to make that happen, while you could fade out the placeholder image during the download, you can't start fade in the new image until the whole image is downloaded.
  • Daniel Campos
    Daniel Campos almost 11 years
    Would be easier make changes into the class.
  • Rob
    Rob almost 11 years
    @DanielCampos You could solve the "no progress block" issue easily enough (be forewarned: if you make changes to AFNetworking, you introduce a maintenance hassles re integrating future AFNetworking enhancements/fixes), but the fundamental problem of the "fade as you download" idea, is that you have nothing to fade to. I don't see how you're going to possibly fix that!
  • CyberDandy
    CyberDandy over 9 years
    Don't forget to set weakImageView.image to image in the success block !