Rajan Maheshwari
Rajan Maheshwari

Reputation: 14571

Activity indicator in SdWebImage issue

I have a horizontal collection view and it has 20 cells with UIImageView I just want to show the activity indicator till the image download completed. I am using the new SDWebImage library where we have methods as sd_setImageWithURL Till now What i am doing is

__block UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.center = cell.photoOneImageView.center;
activityIndicator.hidesWhenStopped = YES;

[cell.photoOneImageView sd_setImageWithURL:[NSURL URLWithString:@"https://scontent-sjc.xx.fbcdn.net/hphotos-xpa1/v/t1.0-9/p480x480/11073324_10153728863852926_4010319763478440264_n.jpg?oh=590934059508b7da235a46fc39e08063&oe=55B61458"] 
placeholderImage:[UIImage imageNamed:@"placeholder.jpg"] 
completed:^(UIImage *image, NSError *error,  SDImageCacheType cacheType, NSURL *imageURL) {
    [activityIndicator stopAnimating];
    [activityIndicator removeFromSuperview];
    }];

[cell.photoOneImageView addSubview:activityIndicator];
[activityIndicator startAnimating];

I am writing this code in cellForItemAtIndexPath method It shows sometimes multiple indicators on 1 cell and they are not removing also sometimes when we scroll the collection view horizontally.

I saw this https://github.com/rs/SDNetworkActivityIndicator but I am unable to use this. No luck with that. Has anyone implemented activity indicator in tebleview cell or collection view cell when the image completed the indicator vanish. Please help. Any help will be appreciated. Thanks

Upvotes: 3

Views: 5902

Answers (5)

Ankit Kumar Gupta
Ankit Kumar Gupta

Reputation: 4042

Best way is to use SDWebImage's default activity indicator available in the latest repo

Updates: SWIFT 5 SDWebImage 5.x.x

        cell.imageView.sd_imageIndicator = SDWebImageActivityIndicator.gray
        cell.imageView.sd_setImage(with: url) { (image, error, cache, urls) in
            if (error != nil) {
                // Failed to load image
                cell.imageView.image = UIImage(named: "ico_placeholder")
            } else {
                // Successful in loading image
                cell.imageView.image = image
            }
        }

swift 3 :

cell.imageView.setShowActivityIndicator(true)
cell.imageView.setIndicatorStyle(.gray)
cell.imageView?.sd_setImage(with: url) { (image, error, cache, urls) in
                if (error != nil) {
                    // Failed to load image
                    cell.imageView.image = UIImage(named: "ico_placeholder")
                } else {
                    // Successful in loading image
                    cell.imageView.image = image
                }
 }

Upvotes: 5

Ajjjjjjjj
Ajjjjjjjj

Reputation: 675

you have to create a separate CollectionView cell, to get reused.

or just do this after creating collectionviewcell:

  for (__strong UIView *view in Cell.contentView.subviews) {
if([view isKindofClass: [UIActivityIndicatorView class]]])
{

        [view removeFromSuperview];
        view = nil;}
    }

Because you are always creating new object of activityindicatorView

Upvotes: 0

Giang
Giang

Reputation: 3635

swift 3 For extension UIImageView+Download+Extension.swift:

import SDWebImage

extension UIImageView {
    func setImageWithIndicator(imageUrl: String, callback: ((_ image: UIImage) -> Void)? = nil) {
        guard !imageUrl.isEmpty else {
            return
    }

        if let url = NSURL(string: imageUrl), url.host != nil {
            self.setShowActivityIndicator(true)
            self.setIndicatorStyle(.gray)
            self.sd_setImage(with: url as URL!, completed: { (_, _, _, _) in
        })
     }
   }
}

using:

UIImageView.setImageWithIndicator(imageUrl: url)

Upvotes: 0

Pedro Mancheno
Pedro Mancheno

Reputation: 5237

The issue you are having is that you are adding a UIActivityIndicatorView on a cell that might get dequed and reused later on before your block triggers.

To fix this, make the activity indicator a property of your cell:

@interface Cell : UICollectionViewCell

@property (strong, nonatomic) UIActivityIndicatorView activityIndicator;

@end

Then, your implementation should look like this:

@implementation Cell

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initialize];
    }
    return self;
}

- (void)awakeFromNib
{
    [super awakeFromNib];
    [self initialize];
}

- (void)initialize
{
    // This code is only called once
    self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    self.activityIndicator.center = self.photoOneImageView.center;
    self.activityIndicator.hidesWhenStopped = YES;
    [self.photoOneImageView addSubview:self.activityIndicator];
}

@end

Then:

[cell.photoOneImageView sd_setImageWithURL:[NSURL URLWithString:@"https://somesite.com/pic.jpg"] 
                          placeholderImage:[UIImage imageNamed:@"placeholder.jpg"] 
                                 completed:
    ^(UIImage *image, NSError *error,  SDImageCacheType cacheType, NSURL *imageURL) {
        [cell.activityIndicator stopAnimating];
    }];

[cell.activityIndicator startAnimating];

Upvotes: 2

Nhu Nguyen
Nhu Nguyen

Reputation: 874

You can use the library https://github.com/JJSaccolo/UIActivityIndicator-for-SDWebImage to fix the issue.

Very simple to load image with an activity indicator

[cell.photoOneImageView setImageWithURL:[NSURL URLWithString:@"https://scontent-sjc.xx.fbcdn.net/hphotos-xpa1/v/t1.0-9/p480x480/11073324_10153728863852926_4010319763478440264_n.jpg?oh=590934059508b7da235a46fc39e08063&oe=55B61458"] 
        placeholderImage:[UIImage imageNamed:@"placeholder.jpg"]
    usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

Upvotes: 0

Related Questions