Reputation: 14571
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
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
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
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
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
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