New file |
| | |
| | | /* |
| | | * This file is part of the SDWebImage package. |
| | | * (c) Olivier Poitrey <rs@dailymotion.com> |
| | | * |
| | | * For the full copyright and license information, please view the LICENSE |
| | | * file that was distributed with this source code. |
| | | */ |
| | | |
| | | #import "UIImageView+WebCache.h" |
| | | #import "objc/runtime.h" |
| | | #import "UIView+WebCacheOperation.h" |
| | | #import "UIView+WebCache.h" |
| | | |
| | | @implementation UIImageView (WebCache) |
| | | |
| | | - (void)sd_setImageWithURL:(nullable NSURL *)url { |
| | | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; |
| | | } |
| | | |
| | | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { |
| | | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; |
| | | } |
| | | |
| | | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { |
| | | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; |
| | | } |
| | | |
| | | - (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { |
| | | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; |
| | | } |
| | | |
| | | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { |
| | | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; |
| | | } |
| | | |
| | | - (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { |
| | | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; |
| | | } |
| | | |
| | | - (void)sd_setImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder |
| | | options:(SDWebImageOptions)options |
| | | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock |
| | | completed:(nullable SDExternalCompletionBlock)completedBlock { |
| | | [self sd_internalSetImageWithURL:url |
| | | placeholderImage:placeholder |
| | | options:options |
| | | operationKey:nil |
| | | setImageBlock:nil |
| | | progress:progressBlock |
| | | completed:completedBlock]; |
| | | } |
| | | |
| | | - (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url |
| | | placeholderImage:(nullable UIImage *)placeholder |
| | | options:(SDWebImageOptions)options |
| | | progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock |
| | | completed:(nullable SDExternalCompletionBlock)completedBlock { |
| | | NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url]; |
| | | UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromCacheForKey:key]; |
| | | |
| | | [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock]; |
| | | } |
| | | |
| | | #if SD_UIKIT |
| | | |
| | | #pragma mark - Animation of multiple images |
| | | |
| | | - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs { |
| | | [self sd_cancelCurrentAnimationImagesLoad]; |
| | | NSPointerArray *operationsArray = [self sd_animationOperationArray]; |
| | | |
| | | [arrayOfURLs enumerateObjectsUsingBlock:^(NSURL *logoImageURL, NSUInteger idx, BOOL * _Nonnull stop) { |
| | | __weak __typeof(self) wself = self; |
| | | id <SDWebImageOperation> operation = [[SDWebImageManager sharedManager] loadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { |
| | | __strong typeof(wself) sself = wself; |
| | | if (!sself) return; |
| | | dispatch_main_async_safe(^{ |
| | | [sself stopAnimating]; |
| | | if (sself && image) { |
| | | NSMutableArray<UIImage *> *currentImages = [[sself animationImages] mutableCopy]; |
| | | if (!currentImages) { |
| | | currentImages = [[NSMutableArray alloc] init]; |
| | | } |
| | | |
| | | // We know what index objects should be at when they are returned so |
| | | // we will put the object at the index, filling any empty indexes |
| | | // with the image that was returned too "early". These images will |
| | | // be overwritten. (does not require additional sorting datastructure) |
| | | while ([currentImages count] < idx) { |
| | | [currentImages addObject:image]; |
| | | } |
| | | |
| | | currentImages[idx] = image; |
| | | |
| | | sself.animationImages = currentImages; |
| | | [sself setNeedsLayout]; |
| | | } |
| | | [sself startAnimating]; |
| | | }); |
| | | }]; |
| | | @synchronized (self) { |
| | | [operationsArray addPointer:(__bridge void *)(operation)]; |
| | | } |
| | | }]; |
| | | } |
| | | |
| | | static char animationLoadOperationKey; |
| | | |
| | | // element is weak because operation instance is retained by SDWebImageManager's runningOperations property |
| | | // we should use lock to keep thread-safe because these method may not be acessed from main queue |
| | | - (NSPointerArray *)sd_animationOperationArray { |
| | | @synchronized(self) { |
| | | NSPointerArray *operationsArray = objc_getAssociatedObject(self, &animationLoadOperationKey); |
| | | if (operationsArray) { |
| | | return operationsArray; |
| | | } |
| | | operationsArray = [NSPointerArray weakObjectsPointerArray]; |
| | | objc_setAssociatedObject(self, &animationLoadOperationKey, operationsArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
| | | return operationsArray; |
| | | } |
| | | } |
| | | |
| | | - (void)sd_cancelCurrentAnimationImagesLoad { |
| | | NSPointerArray *operationsArray = [self sd_animationOperationArray]; |
| | | if (operationsArray) { |
| | | @synchronized (self) { |
| | | for (id operation in operationsArray) { |
| | | if ([operation conformsToProtocol:@protocol(SDWebImageOperation)]) { |
| | | [operation cancel]; |
| | | } |
| | | } |
| | | operationsArray.count = 0; |
| | | } |
| | | } |
| | | } |
| | | #endif |
| | | |
| | | @end |