Add the support for watchOS to use View Category method (sd_setImageWithURL:) on WKInterfaceImage

This commit is contained in:
DreamPiggy 2018-05-24 01:48:08 +08:00
parent 522e729094
commit 994bf0fe38
8 changed files with 54 additions and 40 deletions

View File

@ -29,9 +29,11 @@
// This method is called when watch view controller is about to be visible to user
[super willActivate];
NSString *urlString = @"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png";
[[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:urlString] options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
self.imageInterface.image = image;
NSString *urlString = @"http://apng.onevcat.com/assets/elephant.png";
WKInterfaceImage *imageInterface = self.imageInterface;
[imageInterface sd_setImageWithURL:[NSURL URLWithString:urlString] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
// `WKInterfaceImage` unlike `UIImageView`. Even the image is animated image, you should explicitly call `startAnimating` to play animation.
[imageInterface startAnimating];
}];
}

View File

@ -72,6 +72,12 @@
#endif
#if SD_WATCH
#import <WatchKit/WatchKit.h>
#ifndef UIView
#define UIView WKInterfaceObject
#endif
#ifndef UIImageView
#define UIImageView WKInterfaceImage
#endif
#endif
#endif

View File

@ -7,9 +7,6 @@
*/
#import "SDWebImageCompat.h"
#if SD_UIKIT || SD_MAC
#import "SDWebImageManager.h"
/**
@ -197,5 +194,3 @@
#endif
@end
#endif

View File

@ -7,9 +7,6 @@
*/
#import "UIImageView+WebCache.h"
#if SD_UIKIT || SD_MAC
#import "objc/runtime.h"
#import "UIView+WebCacheOperation.h"
#import "UIView+WebCache.h"
@ -138,5 +135,3 @@ static char animationLoadOperationKey;
#endif
@end
#endif

View File

@ -7,9 +7,6 @@
*/
#import "SDWebImageCompat.h"
#if SD_UIKIT || SD_MAC
#import "SDWebImageDefine.h"
#import "SDWebImageManager.h"
#import "SDWebImageTransition.h"
@ -77,6 +74,8 @@ typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable ima
*/
- (void)sd_cancelCurrentImageLoad;
#if SD_UIKIT || SD_MAC
#pragma mark - Image Transition
/**
@ -94,6 +93,6 @@ typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable ima
*/
@property (nonatomic, strong, nullable) id<SDWebImageIndicator> sd_imageIndicator;
@end
#endif
@end

View File

@ -7,9 +7,6 @@
*/
#import "UIView+WebCache.h"
#if SD_UIKIT || SD_MAC
#import "objc/runtime.h"
#import "UIView+WebCacheOperation.h"
#import "SDWebImageError.h"
@ -79,8 +76,10 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
self.sd_imageProgress.totalUnitCount = 0;
self.sd_imageProgress.completedUnitCount = 0;
#if SD_UIKIT || SD_MAC
// check and start image indicator
[self sd_startImageIndicator];
#endif
SDWebImageManager *manager;
if ([context valueForKey:SDWebImageContextCustomManager]) {
@ -89,8 +88,6 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
manager = [SDWebImageManager sharedManager];
}
id<SDWebImageIndicator> imageIndicator = self.sd_imageIndicator;
__weak __typeof(self)wself = self;
SDWebImageDownloaderProgressBlock combinedProgressBlock = ^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
wself.sd_imageProgress.totalUnitCount = expectedSize;
@ -98,12 +95,15 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
if (progressBlock) {
progressBlock(receivedSize, expectedSize, targetURL);
}
#if SD_UIKIT || SD_MAC
id<SDWebImageIndicator> imageIndicator = wself.sd_imageIndicator;
if ([imageIndicator respondsToSelector:@selector(updateIndicatorProgress:)]) {
double progress = wself.sd_imageProgress.fractionCompleted;
dispatch_async(dispatch_get_main_queue(), ^{
[imageIndicator updateIndicatorProgress:progress];
});
}
#endif
};
id <SDWebImageOperation> operation = [manager loadImageWithURL:url options:options context:context progress:combinedProgressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
__strong __typeof (wself) sself = wself;
@ -114,10 +114,12 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
sself.sd_imageProgress.completedUnitCount = SDWebImageProgressUnitCountUnknown;
}
#if SD_UIKIT || SD_MAC
// check and stop image indicator
if (finished) {
[self sd_stopImageIndicator];
}
#endif
BOOL shouldCallCompletedBlock = finished || (options & SDWebImageAvoidAutoSetImage);
BOOL shouldNotSetImage = ((image && (options & SDWebImageAvoidAutoSetImage)) ||
@ -152,16 +154,22 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
targetData = nil;
}
#if SD_UIKIT || SD_MAC
// check whether we should use the image transition
SDWebImageTransition *transition = nil;
if (finished && (options & SDWebImageForceTransition || cacheType == SDImageCacheTypeNone)) {
transition = sself.sd_imageTransition;
}
#endif
if (group) {
dispatch_group_enter(group);
dispatch_main_async_safe(^{
#if SD_UIKIT || SD_MAC
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL];
#else
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
#endif
});
// ensure completion block is called after custom setImage process finish
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
@ -169,14 +177,20 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
});
} else {
dispatch_main_async_safe(^{
#if SD_UIKIT || SD_MAC
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL];
#else
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
#endif
callCompletedBlockClojure();
});
}
}];
[self sd_setImageLoadOperation:operation forKey:validOperationKey];
} else {
#if SD_UIKIT || SD_MAC
[self sd_stopImageIndicator];
#endif
dispatch_main_async_safe(^{
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey : @"Image url is nil"}];
@ -191,23 +205,31 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
}
- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock {
#if SD_UIKIT || SD_MAC
[self sd_setImage:image imageData:imageData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:nil cacheType:0 imageURL:nil];
#else
// watchOS does not support view transition. Simplify the logic
if (setImageBlock) {
setImageBlock(image, imageData);
} else if ([self isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)self;
[imageView setImage:image];
}
#endif
}
#if SD_UIKIT || SD_MAC
- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock transition:(SDWebImageTransition *)transition cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL {
UIView *view = self;
SDSetImageBlock finalSetImageBlock;
if (setImageBlock) {
finalSetImageBlock = setImageBlock;
}
#if SD_UIKIT || SD_MAC
else if ([view isKindOfClass:[UIImageView class]]) {
} else if ([view isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)view;
finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData) {
imageView.image = setImage;
};
}
#endif
#if SD_UIKIT
else if ([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
@ -273,15 +295,20 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
}
}
}
#endif
- (void)sd_setNeedsLayout {
#if SD_UIKIT
[self setNeedsLayout];
#elif SD_MAC
[self setNeedsLayout:YES];
#elif SD_WATCH
// Do nothing because WatchKit automatically layout the view after property change
#endif
}
#if SD_UIKIT || SD_MAC
#pragma mark - Image Transition
- (SDWebImageTransition *)sd_imageTransition {
return objc_getAssociatedObject(self, @selector(sd_imageTransition));
@ -340,6 +367,6 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
});
}
@end
#endif
@end

View File

@ -7,10 +7,7 @@
*/
#import "SDWebImageCompat.h"
#if SD_UIKIT || SD_MAC
#import "SDWebImageManager.h"
#import "SDWebImageOperation.h"
// These methods are used to support canceling for UIView image loading, it's designed to be used internal but not external.
// All the stored operations are weak, so it will be dalloced after image loading finished. If you need to store operations, use your own class to keep a strong reference for them.
@ -47,5 +44,3 @@
- (void)sd_removeImageLoadOperationWithKey:(nullable NSString *)key;
@end
#endif

View File

@ -7,9 +7,6 @@
*/
#import "UIView+WebCacheOperation.h"
#if SD_UIKIT || SD_MAC
#import "objc/runtime.h"
static char loadOperationKey;
@ -80,5 +77,3 @@ typedef NSMapTable<NSString *, id<SDWebImageOperation>> SDOperationsDictionary;
}
@end
#endif