Skip to content

Commit 2cfa5cc

Browse files
committed
Loading Indicator view with 2 lines of code
added support for UIActivityIndicatorView while the image is downloaded, without adding extra ‘setImageWithUrl’ methods to the UIImageView+WebCache category. I used [this pull request](https://github.com/mythodeia/UIActivityIndicator-for-SDWebImage ), original author is [JJSaccolo](https://github.com/JJSaccolo), and modded it a bit to support loading indicator while the image is downloading. the usage is basically this right before the usual sd_setImage... methods: ``` // show activity indicator [cell.imageView setShowActivityIndicatorView:YES]; // choose indicator style [cell.imageView setIndicatorStyle:UIActivityIndicatorViewStyleGray]; ```
1 parent afd1931 commit 2cfa5cc

File tree

3 files changed

+85
-3
lines changed

3 files changed

+85
-3
lines changed

Examples/SDWebImage Demo/MasterViewController.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
377377
if (cell == nil)
378378
{
379379
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
380+
// show activity indicator
381+
[cell.imageView setShowActivityIndicatorView:YES];
382+
// choose indicator style
383+
[cell.imageView setIndicatorStyle:UIActivityIndicatorViewStyleGray];
380384
}
381385

382386
cell.textLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row];

SDWebImage/UIImageView+WebCache.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,16 @@
176176

177177
- (void)sd_cancelCurrentAnimationImagesLoad;
178178

179+
/**
180+
* Show activity UIActivityIndicatorView
181+
*/
182+
- (void)setShowActivityIndicatorView:(BOOL)show;
183+
184+
/**
185+
* set desired UIActivityIndicatorViewStyle
186+
*
187+
* @param style The style of the UIActivityIndicatorView
188+
*/
189+
- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style;
190+
179191
@end

SDWebImage/UIImageView+WebCache.m

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#import "UIView+WebCacheOperation.h"
1212

1313
static char imageURLKey;
14+
static char TAG_ACTIVITY_INDICATOR;
15+
static char TAG_ACTIVITY_STYLE;
16+
static char TAG_ACTIVITY_SHOW;
1417

1518
@implementation UIImageView (WebCache)
1619

@@ -47,13 +50,19 @@ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
4750
self.image = placeholder;
4851
});
4952
}
50-
53+
54+
// check if activityView is enabled or not
55+
if ([self showActivityIndicatorView]) {
56+
[self addActivityIndicator];
57+
}
58+
5159
if (url) {
5260
__weak UIImageView *wself = self;
5361
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
5462
if (!wself) return;
5563
dispatch_main_sync_safe(^{
5664
if (!wself) return;
65+
[wself removeActivityIndicator];
5766
if (image) {
5867
wself.image = image;
5968
[wself setNeedsLayout];
@@ -71,6 +80,7 @@ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
7180
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
7281
} else {
7382
dispatch_main_async_safe(^{
83+
[self removeActivityIndicator];
7484
NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
7585
if (completedBlock) {
7686
completedBlock(nil, error, SDImageCacheTypeNone, url);
@@ -82,8 +92,8 @@ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
8292
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
8393
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
8494
UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key];
85-
86-
[self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock];
95+
96+
[self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock];
8797
}
8898

8999
- (NSURL *)sd_imageURL {
@@ -129,4 +139,60 @@ - (void)sd_cancelCurrentAnimationImagesLoad {
129139
[self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];
130140
}
131141

142+
- (UIActivityIndicatorView *)activityIndicator {
143+
return (UIActivityIndicatorView *)objc_getAssociatedObject(self, &TAG_ACTIVITY_INDICATOR);
144+
}
145+
- (void)setActivityIndicator:(UIActivityIndicatorView *)activityIndicator {
146+
objc_setAssociatedObject(self, &TAG_ACTIVITY_INDICATOR, activityIndicator, OBJC_ASSOCIATION_RETAIN);
147+
}
148+
149+
- (void)setShowActivityIndicatorView:(BOOL)show{
150+
objc_setAssociatedObject(self, &TAG_ACTIVITY_SHOW, [NSNumber numberWithBool:show], OBJC_ASSOCIATION_RETAIN);
151+
}
152+
- (BOOL)showActivityIndicatorView{
153+
return [objc_getAssociatedObject(self, &TAG_ACTIVITY_SHOW) boolValue];
154+
}
155+
156+
- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style{
157+
objc_setAssociatedObject(self, &TAG_ACTIVITY_STYLE, [NSNumber numberWithInt:style], OBJC_ASSOCIATION_RETAIN);
158+
}
159+
- (int)getIndicatorStyle{
160+
return [objc_getAssociatedObject(self, &TAG_ACTIVITY_STYLE) intValue];
161+
}
162+
163+
- (void)addActivityIndicator {
164+
if (!self.activityIndicator) {
165+
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:[self getIndicatorStyle]];
166+
self.activityIndicator.autoresizingMask = UIViewAutoresizingNone;
167+
168+
dispatch_async(dispatch_get_main_queue(), ^(void) {
169+
[self addSubview:self.activityIndicator];
170+
[self updateActivityIndicatorFrame];
171+
});
172+
}
173+
174+
dispatch_async(dispatch_get_main_queue(), ^(void) {
175+
[self.activityIndicator startAnimating];
176+
});
177+
178+
}
179+
- (void)updateActivityIndicatorFrame {
180+
if (self.activityIndicator) {
181+
CGRect activityIndicatorBounds = self.activityIndicator.bounds;
182+
float x = (self.frame.size.width - activityIndicatorBounds.size.width) / 2.0;
183+
float y = (self.frame.size.height - activityIndicatorBounds.size.height) / 2.0;
184+
self.activityIndicator.frame = CGRectMake(x, y, activityIndicatorBounds.size.width, activityIndicatorBounds.size.height);
185+
}
186+
}
187+
- (void)removeActivityIndicator {
188+
if (self.activityIndicator) {
189+
[self.activityIndicator removeFromSuperview];
190+
self.activityIndicator = nil;
191+
}
192+
}
193+
- (void)layoutSubviews {
194+
[super layoutSubviews];
195+
[self updateActivityIndicatorFrame];
196+
}
197+
132198
@end

0 commit comments

Comments
 (0)