From 8590388a6ecdf8b9927b5af4731a0f3c36e6f51f Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Fri, 19 Jan 2018 15:46:05 +0800 Subject: [PATCH 1/4] Add WebCache category for NSButton on macOS --- SDWebImage.xcodeproj/project.pbxproj | 8 + SDWebImage/NSButton+WebCache.h | 237 +++++++++++++++++++++++++++ SDWebImage/NSButton+WebCache.m | 102 ++++++++++++ WebImage/SDWebImage.h | 1 + 4 files changed, 348 insertions(+) create mode 100644 SDWebImage/NSButton+WebCache.h create mode 100644 SDWebImage/NSButton+WebCache.m diff --git a/SDWebImage.xcodeproj/project.pbxproj b/SDWebImage.xcodeproj/project.pbxproj index 270e37b9..b503d080 100644 --- a/SDWebImage.xcodeproj/project.pbxproj +++ b/SDWebImage.xcodeproj/project.pbxproj @@ -37,6 +37,8 @@ 00733A711BC4880E00A5A117 /* UIImageView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 53922D95148C56230056699D /* UIImageView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; 00733A721BC4880E00A5A117 /* UIView+WebCacheOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AB615301192DA24600A2D8E9 /* UIView+WebCacheOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 00733A731BC4880E00A5A117 /* SDWebImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A2CAE031AB4BB5400B6BC39 /* SDWebImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 321DB3612011D4D70015D2CB /* NSButton+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 321DB35F2011D4D60015D2CB /* NSButton+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 321DB3622011D4D70015D2CB /* NSButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 321DB3602011D4D60015D2CB /* NSButton+WebCache.m */; }; 321E60861F38E8C800405457 /* SDWebImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 321E60841F38E8C800405457 /* SDWebImageCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 321E60871F38E8C800405457 /* SDWebImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 321E60841F38E8C800405457 /* SDWebImageCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 321E60881F38E8C800405457 /* SDWebImageCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 321E60841F38E8C800405457 /* SDWebImageCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1285,6 +1287,8 @@ /* Begin PBXFileReference section */ 00733A4C1BC487C000A5A117 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 321DB35F2011D4D60015D2CB /* NSButton+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSButton+WebCache.h"; path = "SDWebImage/NSButton+WebCache.h"; sourceTree = ""; }; + 321DB3602011D4D60015D2CB /* NSButton+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSButton+WebCache.m"; path = "SDWebImage/NSButton+WebCache.m"; sourceTree = ""; }; 321E60841F38E8C800405457 /* SDWebImageCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageCoder.h; sourceTree = ""; }; 321E60851F38E8C800405457 /* SDWebImageCoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageCoder.m; sourceTree = ""; }; 321E60921F38E8ED00405457 /* SDWebImageImageIOCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageImageIOCoder.h; sourceTree = ""; }; @@ -1640,6 +1644,8 @@ children = ( 4397D2F41D0DE2DF00BB2784 /* NSImage+WebCache.h */, 4397D2F51D0DE2DF00BB2784 /* NSImage+WebCache.m */, + 321DB35F2011D4D60015D2CB /* NSButton+WebCache.h */, + 321DB3602011D4D60015D2CB /* NSButton+WebCache.m */, 535699B415113E7300A4C397 /* MKAnnotationView+WebCache.h */, 535699B515113E7300A4C397 /* MKAnnotationView+WebCache.m */, 53922D93148C56230056699D /* UIButton+WebCache.h */, @@ -2295,6 +2301,7 @@ 321E60B51F38E90100405457 /* SDWebImageWebPCoder.h in Headers */, 4397D2EB1D0DDD8C00BB2784 /* NSData+ImageContentType.h in Headers */, 80377C851F2F666400F89830 /* huffman_encode_utils.h in Headers */, + 321DB3612011D4D70015D2CB /* NSButton+WebCache.h in Headers */, 807A122D1F89636300EC2A9B /* SDWebImageCodersManager.h in Headers */, 4397D2ED1D0DDD8C00BB2784 /* mux_types.h in Headers */, 80377C831F2F666400F89830 /* filters_utils.h in Headers */, @@ -3198,6 +3205,7 @@ 80377C8C1F2F666400F89830 /* random_utils.c in Sources */, 323F8BAD1F38EF770092B609 /* picture_psnr_enc.c in Sources */, 323F8BC51F38EF770092B609 /* quant_enc.c in Sources */, + 321DB3622011D4D70015D2CB /* NSButton+WebCache.m in Sources */, 80377C7F1F2F666400F89830 /* color_cache_utils.c in Sources */, 80377E331F2F66A800F89830 /* alpha_processing_neon.c in Sources */, 80377E401F2F66A800F89830 /* dec_clip_tables.c in Sources */, diff --git a/SDWebImage/NSButton+WebCache.h b/SDWebImage/NSButton+WebCache.h new file mode 100644 index 00000000..56b45a56 --- /dev/null +++ b/SDWebImage/NSButton+WebCache.h @@ -0,0 +1,237 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" + +#if SD_MAC + +#import "SDWebImageManager.h" + +@interface NSButton (WebCache) + +#pragma mark - Image + +/** + * Set the button `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `image` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrieved from the local cache or from the network. + * The fourth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +#pragma mark - Alternate Image + +/** + * Set the button `alternateImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url NS_REFINED_FOR_SWIFT; + +/** + * Set the button `alternateImage` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @see sd_setAlternateImageWithURL:placeholderImage:options: + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT; + +/** + * Set the button `alternateImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param options The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT; + +/** + * Set the button `alternateImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `alternateImage` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT; + +/** + * Set the button `alternateImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param options The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + completed:(nullable SDExternalCompletionBlock)completedBlock; + +/** + * Set the button `alternateImage` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the alternateImage. + * @param placeholder The alternateImage to be set initially, until the alternateImage request finishes. + * @param options The options to use when downloading the alternateImage. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while alternateImage is downloading + * @note the progress block is executed on a background queue + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the alternateImage parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the alternateImage was retrieved from the local cache or from the network. + * The fourth parameter is the original alternateImage url. + */ +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock; + +@end + +#endif diff --git a/SDWebImage/NSButton+WebCache.m b/SDWebImage/NSButton+WebCache.m new file mode 100644 index 00000000..ead14f35 --- /dev/null +++ b/SDWebImage/NSButton+WebCache.m @@ -0,0 +1,102 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "NSButton+WebCache.h" + +#if SD_MAC + +#import "UIView+WebCache.h" + +@implementation NSButton (WebCache) + +#pragma mark - Image + +- (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]; +} + +#pragma mark - Alternate Image + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url { + [self sd_setAlternateImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setAlternateImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { + [self sd_setAlternateImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setAlternateImageWithURL:(nullable NSURL *)url + placeholderImage:(nullable UIImage *)placeholder + options:(SDWebImageOptions)options + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock + completed:(nullable SDExternalCompletionBlock)completedBlock { + __weak typeof(self)weakSelf = self; + [self sd_internalSetImageWithURL:url + placeholderImage:placeholder + options:options + operationKey:nil + setImageBlock:^(NSImage * _Nullable image, NSData * _Nullable imageData) { + weakSelf.alternateImage = image; + } + progress:progressBlock + completed:completedBlock]; +} + +@end + +#endif diff --git a/WebImage/SDWebImage.h b/WebImage/SDWebImage.h index e35d1051..5e02f993 100644 --- a/WebImage/SDWebImage.h +++ b/WebImage/SDWebImage.h @@ -54,6 +54,7 @@ FOUNDATION_EXPORT const unsigned char WebImageVersionString[]; #if SD_MAC #import + #import #endif #if SD_UIKIT From 634e4f4522554071946690d542dc7a561ced2568 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Fri, 19 Jan 2018 18:06:20 +0800 Subject: [PATCH 2/4] Fix that reset alternateImage cancel the image load operation for NSButton+WebCache --- SDWebImage/NSButton+WebCache.h | 12 ++++++++++++ SDWebImage/NSButton+WebCache.m | 20 +++++++++++++++++--- SDWebImage/UIButton+WebCache.h | 2 +- SDWebImage/UIButton+WebCache.m | 4 +++- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/SDWebImage/NSButton+WebCache.h b/SDWebImage/NSButton+WebCache.h index 56b45a56..42c3fc69 100644 --- a/SDWebImage/NSButton+WebCache.h +++ b/SDWebImage/NSButton+WebCache.h @@ -232,6 +232,18 @@ progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock; +#pragma mark - Cancel + +/** + * Cancel the current image download + */ +- (void)sd_cancelCurrentImageLoad; + +/** + * Cancel the current alternateImage download + */ +- (void)sd_cancelCurrentAlternateImageLoad; + @end #endif diff --git a/SDWebImage/NSButton+WebCache.m b/SDWebImage/NSButton+WebCache.m index ead14f35..5a012c36 100644 --- a/SDWebImage/NSButton+WebCache.m +++ b/SDWebImage/NSButton+WebCache.m @@ -10,6 +10,7 @@ #if SD_MAC +#import "UIView+WebCacheOperation.h" #import "UIView+WebCache.h" @implementation NSButton (WebCache) @@ -45,11 +46,14 @@ options:(SDWebImageOptions)options progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + __weak typeof(self)weakSelf = self; [self sd_internalSetImageWithURL:url placeholderImage:placeholder options:options - operationKey:nil - setImageBlock:nil + operationKey:@"NSButtonImageOperation" + setImageBlock:^(NSImage * _Nullable image, NSData * _Nullable imageData) { + weakSelf.image = image; + } progress:progressBlock completed:completedBlock]; } @@ -89,7 +93,7 @@ [self sd_internalSetImageWithURL:url placeholderImage:placeholder options:options - operationKey:nil + operationKey:@"NSButtonAlternateImageOperation" setImageBlock:^(NSImage * _Nullable image, NSData * _Nullable imageData) { weakSelf.alternateImage = image; } @@ -97,6 +101,16 @@ completed:completedBlock]; } +#pragma mark - Cancel + +- (void)sd_cancelCurrentImageLoad { + [self sd_cancelImageLoadOperationWithKey:@"NSButtonImageOperation"]; +} + +- (void)sd_cancelCurrentAlternateImageLoad { + [self sd_cancelImageLoadOperationWithKey:@"NSButtonAlternateImageOperation"]; +} + @end #endif diff --git a/SDWebImage/UIButton+WebCache.h b/SDWebImage/UIButton+WebCache.h index b6c4a2a2..61fada62 100644 --- a/SDWebImage/UIButton+WebCache.h +++ b/SDWebImage/UIButton+WebCache.h @@ -128,7 +128,7 @@ options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock; -#pragma mark - Background image +#pragma mark - Background Image /** * Get the current background image URL. diff --git a/SDWebImage/UIButton+WebCache.m b/SDWebImage/UIButton+WebCache.m index 11e34b18..83aebd04 100644 --- a/SDWebImage/UIButton+WebCache.m +++ b/SDWebImage/UIButton+WebCache.m @@ -87,7 +87,7 @@ static inline NSString * backgroundImageURLKeyForState(UIControlState state) { completed:completedBlock]; } -#pragma mark - Background image +#pragma mark - Background Image - (nullable NSURL *)sd_currentBackgroundImageURL { NSURL *url = self.imageURLStorage[backgroundImageURLKeyForState(self.state)]; @@ -146,6 +146,8 @@ static inline NSString * backgroundImageURLKeyForState(UIControlState state) { completed:completedBlock]; } +#pragma mark - Cancel + - (void)sd_cancelImageLoadForState:(UIControlState)state { [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]]; } From 7996b0dac86b31da8458cb654fbaa1b649392e61 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Fri, 19 Jan 2018 18:45:02 +0800 Subject: [PATCH 3/4] Update macOS demo to add a clear cache button using NSButton category --- .../Assets.xcassets/Contents.json | 6 +++++ .../Base.lproj/Main.storyboard | 23 ++++++++++++++++--- Examples/SDWebImage OSX Demo/ViewController.m | 15 ++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 Examples/SDWebImage OSX Demo/Assets.xcassets/Contents.json diff --git a/Examples/SDWebImage OSX Demo/Assets.xcassets/Contents.json b/Examples/SDWebImage OSX Demo/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Examples/SDWebImage OSX Demo/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Examples/SDWebImage OSX Demo/Base.lproj/Main.storyboard b/Examples/SDWebImage OSX Demo/Base.lproj/Main.storyboard index 29684e48..eaa4ae59 100644 --- a/Examples/SDWebImage OSX Demo/Base.lproj/Main.storyboard +++ b/Examples/SDWebImage OSX Demo/Base.lproj/Main.storyboard @@ -1,8 +1,9 @@ - - + + - + + @@ -656,6 +657,9 @@ + + + @@ -675,23 +679,36 @@ + + + + + + diff --git a/Examples/SDWebImage OSX Demo/ViewController.m b/Examples/SDWebImage OSX Demo/ViewController.m index 6a8ec69f..ad534b77 100644 --- a/Examples/SDWebImage OSX Demo/ViewController.m +++ b/Examples/SDWebImage OSX Demo/ViewController.m @@ -16,6 +16,7 @@ @property (weak) IBOutlet NSImageView *imageView2; @property (weak) IBOutlet NSImageView *imageView3; @property (weak) IBOutlet NSImageView *imageView4; +@property (weak) IBOutlet NSButton *clearCacheButton; @end @@ -36,6 +37,20 @@ self.imageView4.wantsLayer = YES; self.imageView4.sd_imageTransition = SDWebImageTransition.fadeTransition; [self.imageView4 sd_setImageWithURL:[NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage001.jpg"] placeholderImage:nil options:SDWebImageForceTransition]; + + self.clearCacheButton.target = self; + self.clearCacheButton.action = @selector(clearCacheButtonClicked:); + [self.clearCacheButton sd_setImageWithURL:[NSURL URLWithString:@"https://png.icons8.com/color/100/000000/delete-sign.png"]]; + [self.clearCacheButton sd_setAlternateImageWithURL:[NSURL URLWithString:@"https://png.icons8.com/color/100/000000/checkmark.png"]]; +} + +- (void)clearCacheButtonClicked:(NSResponder *)sender { + NSButton *button = (NSButton *)sender; + button.state = NSControlStateValueOn; + [[SDImageCache sharedImageCache] clearMemory]; + [[SDImageCache sharedImageCache] clearDiskOnCompletion:^{ + button.state = NSControlStateValueOff; + }]; } - (void)setRepresentedObject:(id)representedObject { From bccdd2a76609058a31ab11e91579d56e9675922d Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Fri, 26 Jan 2018 14:28:50 +0800 Subject: [PATCH 4/4] Add the current image/alternateImage url for NSButton category. A little code refactoring --- SDWebImage/NSButton+WebCache.h | 10 +++++++++ SDWebImage/NSButton+WebCache.m | 39 +++++++++++++++++++++++++++++---- SDWebImage/UIButton+WebCache.m | 40 +++++++++++++++++++++------------- 3 files changed, 70 insertions(+), 19 deletions(-) diff --git a/SDWebImage/NSButton+WebCache.h b/SDWebImage/NSButton+WebCache.h index 42c3fc69..57f7115e 100644 --- a/SDWebImage/NSButton+WebCache.h +++ b/SDWebImage/NSButton+WebCache.h @@ -16,6 +16,11 @@ #pragma mark - Image +/** + * Get the current image URL. + */ +- (nullable NSURL *)sd_currentImageURL; + /** * Set the button `image` with an `url`. * @@ -125,6 +130,11 @@ #pragma mark - Alternate Image +/** + * Get the current alternateImage URL. + */ +- (nullable NSURL *)sd_currentAlternateImageURL; + /** * Set the button `alternateImage` with an `url`. * diff --git a/SDWebImage/NSButton+WebCache.m b/SDWebImage/NSButton+WebCache.m index 5a012c36..3ca080f2 100644 --- a/SDWebImage/NSButton+WebCache.m +++ b/SDWebImage/NSButton+WebCache.m @@ -10,9 +10,18 @@ #if SD_MAC +#import "objc/runtime.h" #import "UIView+WebCacheOperation.h" #import "UIView+WebCache.h" +static inline NSString * imageOperationKey() { + return @"NSButtonImageOperation"; +} + +static inline NSString * alternateImageOperationKey() { + return @"NSButtonAlternateImageOperation"; +} + @implementation NSButton (WebCache) #pragma mark - Image @@ -46,11 +55,13 @@ options:(SDWebImageOptions)options progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + self.sd_currentImageURL = url; + __weak typeof(self)weakSelf = self; [self sd_internalSetImageWithURL:url placeholderImage:placeholder options:options - operationKey:@"NSButtonImageOperation" + operationKey:imageOperationKey() setImageBlock:^(NSImage * _Nullable image, NSData * _Nullable imageData) { weakSelf.image = image; } @@ -89,11 +100,13 @@ options:(SDWebImageOptions)options progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock completed:(nullable SDExternalCompletionBlock)completedBlock { + self.sd_currentAlternateImageURL = url; + __weak typeof(self)weakSelf = self; [self sd_internalSetImageWithURL:url placeholderImage:placeholder options:options - operationKey:@"NSButtonAlternateImageOperation" + operationKey:alternateImageOperationKey() setImageBlock:^(NSImage * _Nullable image, NSData * _Nullable imageData) { weakSelf.alternateImage = image; } @@ -104,11 +117,29 @@ #pragma mark - Cancel - (void)sd_cancelCurrentImageLoad { - [self sd_cancelImageLoadOperationWithKey:@"NSButtonImageOperation"]; + [self sd_cancelImageLoadOperationWithKey:imageOperationKey()]; } - (void)sd_cancelCurrentAlternateImageLoad { - [self sd_cancelImageLoadOperationWithKey:@"NSButtonAlternateImageOperation"]; + [self sd_cancelImageLoadOperationWithKey:alternateImageOperationKey()]; +} + +#pragma mar - Private + +- (NSURL *)sd_currentImageURL { + return objc_getAssociatedObject(self, @selector(sd_currentImageURL)); +} + +- (void)setSd_currentImageURL:(NSURL *)sd_currentImageURL { + objc_setAssociatedObject(self, @selector(sd_currentImageURL), sd_currentImageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (NSURL *)sd_currentAlternateImageURL { + return objc_getAssociatedObject(self, @selector(sd_currentAlternateImageURL)); +} + +- (void)setSd_currentAlternateImageURL:(NSURL *)sd_currentAlternateImageURL { + objc_setAssociatedObject(self, @selector(sd_currentAlternateImageURL), sd_currentAlternateImageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end diff --git a/SDWebImage/UIButton+WebCache.m b/SDWebImage/UIButton+WebCache.m index 83aebd04..8cdadb67 100644 --- a/SDWebImage/UIButton+WebCache.m +++ b/SDWebImage/UIButton+WebCache.m @@ -26,22 +26,30 @@ static inline NSString * backgroundImageURLKeyForState(UIControlState state) { return [NSString stringWithFormat:@"backgroundImage_%lu", (unsigned long)state]; } +static inline NSString * imageOperationKeyForState(UIControlState state) { + return [NSString stringWithFormat:@"UIButtonImageOperation%lu", (unsigned long)state]; +} + +static inline NSString * backgroundImageOperationKeyForState(UIControlState state) { + return [NSString stringWithFormat:@"UIButtonBackgroundImageOperation%lu", (unsigned long)state]; +} + @implementation UIButton (WebCache) #pragma mark - Image - (nullable NSURL *)sd_currentImageURL { - NSURL *url = self.imageURLStorage[imageURLKeyForState(self.state)]; + NSURL *url = self.sd_imageURLStorage[imageURLKeyForState(self.state)]; if (!url) { - url = self.imageURLStorage[imageURLKeyForState(UIControlStateNormal)]; + url = self.sd_imageURLStorage[imageURLKeyForState(UIControlStateNormal)]; } return url; } - (nullable NSURL *)sd_imageURLForState:(UIControlState)state { - return self.imageURLStorage[imageURLKeyForState(state)]; + return self.sd_imageURLStorage[imageURLKeyForState(state)]; } - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state { @@ -70,16 +78,16 @@ static inline NSString * backgroundImageURLKeyForState(UIControlState state) { options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { if (!url) { - [self.imageURLStorage removeObjectForKey:imageURLKeyForState(state)]; + [self.sd_imageURLStorage removeObjectForKey:imageURLKeyForState(state)]; } else { - self.imageURLStorage[imageURLKeyForState(state)] = url; + self.sd_imageURLStorage[imageURLKeyForState(state)] = url; } __weak typeof(self)weakSelf = self; [self sd_internalSetImageWithURL:url placeholderImage:placeholder options:options - operationKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)] + operationKey:imageOperationKeyForState(state) setImageBlock:^(UIImage *image, NSData *imageData) { [weakSelf setImage:image forState:state]; } @@ -90,17 +98,17 @@ static inline NSString * backgroundImageURLKeyForState(UIControlState state) { #pragma mark - Background Image - (nullable NSURL *)sd_currentBackgroundImageURL { - NSURL *url = self.imageURLStorage[backgroundImageURLKeyForState(self.state)]; + NSURL *url = self.sd_imageURLStorage[backgroundImageURLKeyForState(self.state)]; if (!url) { - url = self.imageURLStorage[backgroundImageURLKeyForState(UIControlStateNormal)]; + url = self.sd_imageURLStorage[backgroundImageURLKeyForState(UIControlStateNormal)]; } return url; } - (nullable NSURL *)sd_backgroundImageURLForState:(UIControlState)state { - return self.imageURLStorage[backgroundImageURLKeyForState(state)]; + return self.sd_imageURLStorage[backgroundImageURLKeyForState(state)]; } - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state { @@ -129,16 +137,16 @@ static inline NSString * backgroundImageURLKeyForState(UIControlState state) { options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock { if (!url) { - [self.imageURLStorage removeObjectForKey:backgroundImageURLKeyForState(state)]; + [self.sd_imageURLStorage removeObjectForKey:backgroundImageURLKeyForState(state)]; } else { - self.imageURLStorage[backgroundImageURLKeyForState(state)] = url; + self.sd_imageURLStorage[backgroundImageURLKeyForState(state)] = url; } __weak typeof(self)weakSelf = self; [self sd_internalSetImageWithURL:url placeholderImage:placeholder options:options - operationKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)] + operationKey:backgroundImageOperationKeyForState(state) setImageBlock:^(UIImage *image, NSData *imageData) { [weakSelf setBackgroundImage:image forState:state]; } @@ -149,14 +157,16 @@ static inline NSString * backgroundImageURLKeyForState(UIControlState state) { #pragma mark - Cancel - (void)sd_cancelImageLoadForState:(UIControlState)state { - [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]]; + [self sd_cancelImageLoadOperationWithKey:imageOperationKeyForState(state)]; } - (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state { - [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]]; + [self sd_cancelImageLoadOperationWithKey:backgroundImageOperationKeyForState(state)]; } -- (SDStateImageURLDictionary *)imageURLStorage { +#pragma mark - Private + +- (SDStateImageURLDictionary *)sd_imageURLStorage { SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); if (!storage) { storage = [NSMutableDictionary dictionary];