28

Currently i am integrating SDWebImage in my project by following below things

1)#import "UIButton+WebCache.h"

2)[button setImageWithURL:url placeholderImage:[UIImage imageNamed:@"no_photo.png"]];

So it will show the list of image present in URL above the respective buttons.

But Now i want to show an activity indicator above button when the image is getting downloaded ,So how can i do this?

raaz
  • 12,410
  • 22
  • 64
  • 81

7 Answers7

88

Works like a charm for me :

Swift 3:

imgView.setShowActivityIndicator(true)
imgView.setIndicatorStyle(.gray)
imgView.sd_setImage(with: URL(string: urlString), placeholderImage: UIImage(named: "placeholder"))

Swift 4: (Edit : Updates)

imgView.sd_setShowActivityIndicatorView(true)
imgView.sd_setIndicatorStyle(.gray)
imgView.sd_setImage(with: URL(string: urlString), placeholderImage: UIImage(named: "placeholder"))

Swift 5: SDWebImage (5.x.x)

imgView.sd_imageIndicator = SDWebImageActivityIndicator.gray
imgView.sd_setImage(with: URL(string: urlString), placeholderImage: UIImage(named: "placeholder"))

Updates: For UIButton use this

yourButton.sd_setImage(with: URL(string: urlString), for: .normal)
Ankit Kumar Gupta
  • 3,994
  • 4
  • 31
  • 54
4

Last solution

You can download UIActivityIndicator-for-SDWebImage, which is easiest way to add a UIActivityView to your SDWebImage view. Using CocoaPods, just add this line to your podfile:

pod 'UIActivityIndicator-for-SDWebImage'

You can use one of these lines depending on your preferences:

- (void)setImageWithURL:(NSURL *)url usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock usingActivityIndicatorStyle:(UIActivityIndicatorViewStyle)activityStyle;

Example of Use

Just import

#import <UIActivityIndicator-for-SDWebImage/UIImageView+UIActivityIndicatorForSDWebImage.h>

and use this code

[imageView setImageWithURL:[NSURL URLWithString:@"https://media.licdn.com/mpr/mpr/wc_200_200/p/1/005/07f/0a3/30cb8dd.jpg"] placeholderImage:[UIImage imageNamed:@"myImage.jpg"] usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
E-Riddie
  • 14,660
  • 7
  • 52
  • 74
4

The best way I have found to do this is to use the SDWebImageManager class. Your view controller or some other class will then need to conform to the SDWebImageManagerDelegate protocol.

SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *cachedImage = [manager imageWithURL:url];

if (cachedImage) {
    [button setImage:cachedImage];
    // stop or remove your UIActivityIndicatorView here
}
else {
    [manager downloadWithURL:url delegate:self];
}

Once the image has been downloaded the delegate method will be called:

- (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image {
    [button setImage:image];
    // stop or remove your UIActivityIndicatorView here
}

There is also a delegate method for when an error occurs downloading an image

- (void)webImageManager:(SDWebImageManager *)imageManager didFailWithError:(NSError *)error {
    // Handle error here
}

If you have more than one button you may have problems determining which image belongs to which button after the image has downloaded. In this case you may need to have a button subclass which handles the download as above and then updates its own image.

Hope that helps.

stephenmuss
  • 2,445
  • 2
  • 20
  • 29
3

the best way is to add the activityIndicator in all "setImage" functions in UIImageView+WebCache.m, after that you remove it in "webImageManager:r didFinishWithImage:" , i test it in device and it work smoothly, her's an example :

  - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
 {


UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleWhiteLarge)];
[activity startAnimating];
[activity setCenter:self.center];
[self addSubview:activity];
[activity release];



SDWebImageManager *manager = [SDWebImageManager sharedManager];

UIImage *cachedImage = [manager imageWithURL:url];

if (cachedImage)
{
    // the image is cached -> remove activityIndicator from view
    for (UIView *v in [self subviews])
    {
        if ([v isKindOfClass:[UIActivityIndicatorView class]])
        {
            [activity removeFromSuperview];
        }
    }
}

[self setImageWithURL:url placeholderImage:placeholder options:0];
}

and you remove it with a fade animation ;) :

 - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image
{ 

for (UIView *v in [self subviews])
{
    if ([v isKindOfClass:[UIActivityIndicatorView class]])
    {
       // NSLog(@"-didFinishWithImage-");
        [((UIActivityIndicatorView*)v) stopAnimating];
        [v removeFromSuperview];
    }
}


[UIView beginAnimations:@"fadeAnimation" context:NULL]; 
[UIView setAnimationDuration:0.9];
self.alpha = 0;
self.image = image;
self.alpha=1;
//[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self cache:YES]; 
[UIView commitAnimations];

 }
Red Mak
  • 1,176
  • 2
  • 25
  • 56
  • It's Crashing at my end, giving assertion failure error while loading image. – Gaurav Jul 25 '12 at 09:30
  • i just download and use the last version in github, and it work fine (ios 5.1). and it seems that imageWithURL: is deprecated, ill try to work in a new version for this, but you have to give us some code ( are you using an UIImageView gategorie ? ) – Red Mak Jul 25 '12 at 10:57
  • whenever i am using your code to add activity indicator it will provide me assertion error but without activity indicator other animation code will work like charm. if you try and tell me about new version it will be good for me. – Gaurav Jul 25 '12 at 11:01
3

For swift 5

//pass true for showing indicator View
self.imageView.sd_setShowActivityIndicatorView(true)

//give style value
self.imageView.sd_setIndicatorStyle(UIActivityIndicatorView.Style.gray)

//Set your image as you are want to do
self.imageView.sd_setImage(with: URL(string: self.imageUrl), placeholderImage: UIImage())
pravir
  • 342
  • 2
  • 13
1

For Swift 5 users can use the SDWebImageManager this way

extension UIImageView {
    func getImage(url: String, placeholderImage:  UIImage?, success:@escaping (_ _result : Any? ) -> Void,  failer:@escaping (_ _result : Any? ) -> Void) {
        self.sd_imageIndicator = SDWebImageActivityIndicator.gray
        self.sd_setImage(with: URL(string: url), placeholderImage:  placeholderImage, options: SDWebImageOptions(rawValue: 0), completed: { image, error, cacheType, imageURL in
            // your rest code
            if error == nil {
                self.image = image
                success(true)
            }else {
                failer(false)
            }
        })
    }
}

Usage:-

        var imageFeatureImage: String = ""
        
        if !imageURL.contains("https://") {
            imageFeatureImage = BASE_URL_IMAGE+imageURL
        }
       yourimageView.getImage(url: (imageFeatureImage), placeholderImage: nil) { (success) in
           yourimageView.contentMode = .scaleAspectFill
        } failer: { (failed) in
           yourimageView.image = UIImage.init(named: "placeholder")
           yourimageView.contentMode = .scaleAspectFit
        }
Navdeep Paliwal
  • 349
  • 3
  • 7
0

Objective-C: SDWebImage (5.x.x)

[imgView setSd_imageIndicator:SDWebImageActivityIndicator.grayIndicator];
[imgView sd_setImageWithURL:[NSURL URLWithString: urlString] placeholderImage:nil];
ammar shahid
  • 411
  • 4
  • 17