Show activity indicator in SDWebImage

对着背影说爱祢 提交于 2019-12-03 02:54:17

问题


I'm using SDWebView image and i want to show an Activity Indicator as placeholder, while fetching the image from remote.

I tried Malek's answer here How to show an activity indicator in SDWebImage, but it seems that

UIImage *cachedImage = [manager imageWithURL:url];

is deprecated.

Is there anyone using this library that could tell me how can i insert an Activity Indicator while loading the image?

EDIT

Following the indications of Michael Frederick, i ended up with this code and everything's working fine.

UIActivityIndicatorView *activityIndicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite] autorelease];
activityIndicator.hidesWhenStopped = YES;
activityIndicator.hidden = NO;
[activityIndicator startAnimating];
activityIndicator.center = CGPointMake(self.tipImage.frame.size.width /2, self.tipImage.frame.size.height/2);
[imageView setImageWithURL:[NSURL URLWithString:imageString]
          placeholderImage:nil options:SDWebImageProgressiveDownload
                   success:^(UIImage *image) { [activityIndicator stopAnimating];[activityIndicator removeFromSuperview]; }
                   failure:^(NSError *error) {  [activityIndicator stopAnimating];[activityIndicator removeFromSuperview]; }];

[imageView addSubview:activityIndicator];

回答1:


This fork has support for this functionality. Take a look at the diff.

But, in general, you can do it rather easily without using that fork:

__block UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:activityStyle];
activityIndicator.center = imageView.center;
activityIndicator.hidesWhenStopped = YES;
[imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
               placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                        success:^(UIImage *image) { [activityIndicator removeFromSuperview]; }
                        failure:^(NSError *error) { [activityIndicator removeFromSuperview]; }];

[imageView addSubview:activityIndicator];
[activityIndicator startAnimating];



回答2:


This is how you do it:

[imageView setIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[imageView setShowActivityIndicatorView:true];
[imageView sd_setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"defaultl_image"]];



回答3:


That's my solution. In that file : UIImageView+WebCache.m

Find that method and change like that:

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
{
    UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleGray)];
    [activity startAnimating];
    [activity setFrame:CGRectMake(self.frame.origin.x - 20, self.frame.origin.y - 10, self.frame.size.width, self.frame.size.height)];
    [self addSubview:activity];

    //[self setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];

    [self setImageWithURL:url
         placeholderImage:placeholder
                  options:0
                completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
     {
             [activity removeFromSuperview];
     }];
}



回答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];



回答5:


The above code is slightly wrong. The line 'activityIndicator.center = imageView.center' does not give you the correct coordinates to center the progress view. For me, it was showing the indicator below the cell.

Note - I am using the latest version of the SDWebImage code so the method is slightly different. I am also using a UIButton for the imageView

Try this:

NSURL *url = [NSURL URLWithString:@"www.someimageurl.com"];
__block UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.frame = cell.imageView.bounds;
[cell.imageView addSubview:activityIndicator];
[activityIndicator startAnimating];
[cell.imageView setImageWithURL:url forState:UIControlStateNormal completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
    [activityIndicator removeFromSuperview];
}];



回答6:


I believe with the latest version of sdwebimage this is a better method.

[self.customImageView setImageWithURL:imageURL
                             placeholderImage:nil
                                      options:nil
                                     progress:^(NSUInteger receivedSize, long long expectedSize) { [self.activityIndicator startAnimating]; }
                                    completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) { [self.activityIndicator stopAnimating]; }];

Note: If you don't have a property setup obviously self.activityindicator won't work.

I would use Michael Frederick's example to create the activityindicator instead.




回答7:


SDWebImage has a built in Acitvity Indicator that works perfectly. Try this:

Updates: SWIFT 5 SDWebImage 5.x.x

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

Swift 3:

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



回答8:


Same code as above in SWIFT 4:

let activityIndicator = UIActivityIndicatorView.init(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
    activityIndicator.center = addImage.center
    activityIndicator.hidesWhenStopped = true

    addImage.sd_setImage(with: URL(string: feed.image), completed: { (image: UIImage?, error: Error?, cacheType: SDImageCacheType, imageURL: URL?) in
        activityIndicator.removeFromSuperview()
    })

    addImage.addSubview(activityIndicator)
    activityIndicator.startAnimating()



回答9:


SdWebImage 5.0

YOUR_IMAGEVIEW.sd_imageIndicator = SDWebImageActivityIndicator.gray



回答10:


For Swift 5.0 and SDWebImage 5.0 :

Replace

imageView.sd_setShowActivityIndicatorView(true)
imageView.sd_setIndicatorStyle(.gray)

By

imageView.sd_imageIndicator = SDWebImageActivityIndicator.gray



回答11:


[cell.dreamImageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",dream.thumbnail]] placeholderImage:[UIImage imageNamed:@"dream_bg_2.png"] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {

    CGFloat domandeFloat = [[NSNumber numberWithInt: receivedSize] floatValue];
    CGFloat corretteFloat = [[NSNumber numberWithInt: expectedSize] floatValue];


    float currentProgress = domandeFloat/corretteFloat;

     NSLog(@"progress %f",currentProgress);
    cell.progressView.progress = currentProgress;

    //[self.dreamsTableView reloadData];


} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {

    cell.progressView.hidden = YES;
}];



回答12:


Solution updated for Swift 2.0 for using SDWebImage to load image URL

imageView.setShowActivityIndicatorView(true)

imageView.setIndicatorStyle(.White)



回答13:


Based on Can Ürek's answer you might wanna create a category to make it easier to use across multiple applications and without modify SDWebImage framework.

Header file:

#import <UIKit/UIKit.h>

#import <SDWebImage/UIImageView+WebCache.h>

@interface UIImageView (WebCacheWithActivityIndicator)

- (void)setImageShowingActivityIndicatorWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock;

@end

Implementation file:

#import "UIImageView+WebCacheWithActivityIndicator.h"

@implementation UIImageView (WebCacheWithActivityIndicator)

- (void)setImageShowingActivityIndicatorWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock
{
    UIActivityIndicatorView* activityIndication = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

    [activityIndication setFrame:CGRectMake((self.frame.size.width - activityIndication.frame.size.width) / 2 , (self.frame.size.height - activityIndication.frame.size.height) / 2 , activityIndication.frame.size.width , activityIndication.frame.size.width)];
    [self addSubview:activityIndication];

    [activityIndication startAnimating];

    [self setImageWithURL:url completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {

        if(completedBlock)
        {
            completedBlock(image,error,cacheType);
        }

        [activityIndication stopAnimating];
        [activityIndication removeFromSuperview];
    }];
}
@end

Hope it helps you out guys

Cheers




回答14:


Another solution is to use an animated image as the placeholder image by using:

[UIImage animatedImageNamed:@"animated_placeholder" duration:1]




回答15:


With updated library (Resolved Crash on iOS 8), we have below method -

- (void)sd_setImageWithURL:(NSURL *)url 
{
    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
}

As we can see the option to add progress block and completed block, we can simply add Activity indicator in progress block and remove in completion block.

Customized method to add Activity Indicator here -

- (void)sd_setImageWithURL:(NSURL *)url {

    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
        UIActivityIndicatorView *activity = nil;
        activity = (UIActivityIndicatorView *)[self viewWithTag:100000];
        if (!activity) {
            activity = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
            [activity setTag:100000];
            [activity setHidesWhenStopped:YES];
            [activity setCenter:CGPointMake(self.frame.size.width/2.0f,self.frame.size.height/2.0f)];
            [self addSubview:activity];
        }
        else {
            [activity setCenter:CGPointMake(self.frame.size.width/2.0f,self.frame.size.height/2.0f)];
        }
        [activity startAnimating];

    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        UIActivityIndicatorView *activity = (UIActivityIndicatorView *)[self viewWithTag:100000];
        if ([activity isKindOfClass:[UIActivityIndicatorView class]]) {
            [activity stopAnimating];
        }
    }];
}

This will add UIActivityIndicatorView to the center of UIImageView when image downloading in progress and remove on completion.




回答16:


My list is quite lag when the user scrolling the list up and down repeatedly. I found out that the activityindicator had been added infinitely when the cellForItemAtIndexPath is being repeatedly called.

To solve this, add a tag at your activityindicator:

activityIndicator.tag = 9999;

Before the UIActivityIndicator is being created, add these lines to remove the previous activityindicator before adding the new one:

UIView* toDeleteLoader = [cell viewWithTag:9999];
if(toDeleteLoader != nil){
    [toDeleteLoader removeFromSuperview];
}

Note: tag content can be any numbers that it won't be used in your cell.




回答17:


Best solution that worked for me is below. It is beautiful and encouraging to show progress indicator when image is downloading. I used UICircularSlider as rounded progress view. You can also try it.

    [_imgPost sd_setImageWithURL:urlPost placeholderImage:zeroImage options:SDWebImageContinueInBackground progress:^(NSInteger receivedSize, NSInteger expectedSize)
    {
        CGFloat domandeFloat = [[NSNumber numberWithInteger: receivedSize] floatValue];
        CGFloat corretteFloat = [[NSNumber numberWithInteger: expectedSize] floatValue];


        float currentProgress = (domandeFloat/corretteFloat)*100;

        NSLog(@"progress %.f%%",currentProgress);
        DBG(@"%li, %li", receivedSize, expectedSize);
        [_progress setValue:currentProgress];
    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

        [_progress setHidden:YES];
    }];

Here _progress is an instance of UICircularSlider



来源:https://stackoverflow.com/questions/11262204/show-activity-indicator-in-sdwebimage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!