mrtubis
mrtubis

Reputation: 170

loading image asynchronously in viewDidLoad, with activity indicator

When i'm switching from a view (by clicking on a cell in a table) to a view that displays some images, i'm loading a couple of images from a couple of urls.

I want to display an activity indicator animation while the loading occurs.

I'm doing this loading in viewDidLoad of the new view.

If i'm loading the images synchronously, then (not surprisingly) the animation doesn't work since the request is blocking... If i'm loading the images asynchronously, then (also not surprisingly) the view is opened with blanks instead of images, without waiting for the images to be fetched, which i don't want.

I tried to put all that in the segue code that transforms from the old view to the new one, because i hoped that the view will be switched only after the loading will complete but it didn't matter.

How can I enjoy both worlds? how can i not block the app, display the animation, but transition to the next view only when all the images have been loaded?

Upvotes: 2

Views: 1875

Answers (5)

Cherpak Evgeny
Cherpak Evgeny

Reputation: 2770

Check SDWebImage (https://github.com/rs/SDWebImage), it has something called prefetcher - which will download the images and save them in cache, after which you will receive a callback, and can transition to the new view. Needless to say that you will have to show a spinner (SVProgressHUD or MBProgressHUD), and stop it once prefetch callback returns.

https://github.com/rs/SDWebImage/blob/master/SDWebImage/SDWebImagePrefetcher.h

/**
 * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
 * currently one image is downloaded at a time,
 * and skips images for failed downloads and proceed to the next image in the list
 *
 * @param urls list of URLs to prefetch
 */
- (void)prefetchURLs:(NSArray *)urls;

To show those images in your imageView, just use setImageWithURL: method (UIImageView+WebCache category).

Upvotes: 0

Alfred Zien
Alfred Zien

Reputation: 1044

If you don’t want to show certain views while you loading images you can simply hide it, like this self.imageView.hidden = YES; After loading you can set your images, and then set hidden to NO.

If you, for some reason, don’t want to segue to another view, before loading completes, then I think you can make intermediate view, where you’ll download all images, after that segue to your images view, and send that images through prepareForSegue:sender:.

And answer from Aurelien Cobb cleared out how to load images asynchronously.

Upvotes: 0

ismailgulek
ismailgulek

Reputation: 1029

You should take a look at AsyncImageView. It does exactly what you want to do.

You can find it at: https://github.com/nicklockwood/AsyncImageView

Upvotes: 0

Aurelien Cobb
Aurelien Cobb

Reputation: 435

If you don't want to use third party libraries, you can use GCD (Grand central dispatch) like this:

dispatch_queue_t imageLoadingQueue = dispatch_queue_create("imageLoadingQueue", NULL);
// start the loading spinner here
dispatch_async(imageLoadingQueue, ^{
    NSString * urlString = // your URL string here
    NSData * imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
    UIImage * image = [UIImage imageWithData:imageData];
    dispatch_async(dispatch_get_main_queue(), ^{
        // stop the loading spinner here and place the image in your view
    });
});

Upvotes: 3

lootsch
lootsch

Reputation: 1865

Have a look at AFNetworking and their UIImageView Extension:

setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholderImage;

Asynchronously downloads an image from the specified URL, and sets it once the request is finished.
If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished.

Upvotes: 0

Related Questions