Authored by DreamPiggy

Add the image transition argument for all UIView+WebCache, make this easy for us…

…er to do some fade transition. It also reuse the current setImageBlock and make it easy to customize
... ... @@ -117,6 +117,7 @@
MyCustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.customImageView.sd_imageTransition = SDWebImageTransition.fadeTransition;
}
[cell.customImageView sd_setShowActivityIndicatorView:YES];
... ...
... ... @@ -33,7 +33,9 @@
[self.imageView1 sd_setImageWithURL:[NSURL URLWithString:@"http://assets.sbnation.com/assets/2512203/dogflops.gif"]];
[self.imageView2 sd_setImageWithURL:[NSURL URLWithString:@"http://www.ioncannon.net/wp-content/uploads/2011/06/test2.webp"]];
[self.imageView3 sd_setImageWithURL:[NSURL URLWithString:@"http://littlesvr.ca/apng/images/SteamEngine.webp"]];
[self.imageView4 sd_setImageWithURL:[NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage001.jpg"]];
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];
}
- (void)setRepresentedObject:(id)representedObject {
... ...
... ... @@ -307,6 +307,18 @@
323F8C1D1F38EF770092B609 /* muxread.c in Sources */ = {isa = PBXBuildFile; fileRef = 323F8B3D1F38EF770092B609 /* muxread.c */; };
323F8C1E1F38EF770092B609 /* muxread.c in Sources */ = {isa = PBXBuildFile; fileRef = 323F8B3D1F38EF770092B609 /* muxread.c */; };
323F8C1F1F38EF770092B609 /* muxread.c in Sources */ = {isa = PBXBuildFile; fileRef = 323F8B3D1F38EF770092B609 /* muxread.c */; };
325312C8200F09910046BF1E /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 325312C6200F09910046BF1E /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };
325312C9200F09910046BF1E /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 325312C6200F09910046BF1E /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };
325312CA200F09910046BF1E /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 325312C6200F09910046BF1E /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };
325312CB200F09910046BF1E /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 325312C6200F09910046BF1E /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };
325312CC200F09910046BF1E /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 325312C6200F09910046BF1E /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };
325312CD200F09910046BF1E /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 325312C6200F09910046BF1E /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; };
325312CE200F09910046BF1E /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312C7200F09910046BF1E /* SDWebImageTransition.m */; };
325312CF200F09910046BF1E /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312C7200F09910046BF1E /* SDWebImageTransition.m */; };
325312D0200F09910046BF1E /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312C7200F09910046BF1E /* SDWebImageTransition.m */; };
325312D1200F09910046BF1E /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312C7200F09910046BF1E /* SDWebImageTransition.m */; };
325312D2200F09910046BF1E /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312C7200F09910046BF1E /* SDWebImageTransition.m */; };
325312D3200F09910046BF1E /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312C7200F09910046BF1E /* SDWebImageTransition.m */; };
3290FA041FA478AF0047D20C /* SDWebImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 3290FA021FA478AF0047D20C /* SDWebImageFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
3290FA051FA478AF0047D20C /* SDWebImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 3290FA021FA478AF0047D20C /* SDWebImageFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
3290FA061FA478AF0047D20C /* SDWebImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 3290FA021FA478AF0047D20C /* SDWebImageFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
... ... @@ -1318,6 +1330,8 @@
323F8B3B1F38EF770092B609 /* muxi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = muxi.h; sourceTree = "<group>"; };
323F8B3C1F38EF770092B609 /* muxinternal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = muxinternal.c; sourceTree = "<group>"; };
323F8B3D1F38EF770092B609 /* muxread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = muxread.c; sourceTree = "<group>"; };
325312C6200F09910046BF1E /* SDWebImageTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTransition.h; sourceTree = "<group>"; };
325312C7200F09910046BF1E /* SDWebImageTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTransition.m; sourceTree = "<group>"; };
3290FA021FA478AF0047D20C /* SDWebImageFrame.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageFrame.h; sourceTree = "<group>"; };
3290FA031FA478AF0047D20C /* SDWebImageFrame.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageFrame.m; sourceTree = "<group>"; };
32CF1C051FA496B000004BD1 /* SDWebImageCoderHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageCoderHelper.h; sourceTree = "<group>"; };
... ... @@ -1797,6 +1811,8 @@
53922D8F148C56230056699D /* SDWebImageManager.m */,
53922D91148C56230056699D /* SDWebImagePrefetcher.h */,
53922D92148C56230056699D /* SDWebImagePrefetcher.m */,
325312C6200F09910046BF1E /* SDWebImageTransition.h */,
325312C7200F09910046BF1E /* SDWebImageTransition.m */,
);
name = Utils;
sourceTree = "<group>";
... ... @@ -2024,6 +2040,7 @@
80377C481F2F666300F89830 /* bit_reader_utils.h in Headers */,
80377C511F2F666300F89830 /* huffman_encode_utils.h in Headers */,
00733A6B1BC4880E00A5A117 /* NSData+ImageContentType.h in Headers */,
325312CB200F09910046BF1E /* SDWebImageTransition.h in Headers */,
323F8C111F38EF770092B609 /* muxi.h in Headers */,
80377EC41F2F66D500F89830 /* vp8li_dec.h in Headers */,
00733A6A1BC4880E00A5A117 /* SDWebImagePrefetcher.h in Headers */,
... ... @@ -2093,6 +2110,7 @@
80377EA11F2F66D400F89830 /* vp8_dec.h in Headers */,
80377C271F2F666300F89830 /* rescaler_utils.h in Headers */,
323F8B511F38EF770092B609 /* backward_references_enc.h in Headers */,
325312C9200F09910046BF1E /* SDWebImageTransition.h in Headers */,
43A918651D8308FE00B3925F /* SDImageCacheConfig.h in Headers */,
4314D1741D0E0E3B004B36C9 /* types.h in Headers */,
4314D1761D0E0E3B004B36C9 /* decode.h in Headers */,
... ... @@ -2169,6 +2187,7 @@
431BB6E91D06D2C1006A3455 /* SDWebImageDownloaderOperation.h in Headers */,
80377ED41F2F66D500F89830 /* vp8li_dec.h in Headers */,
431BB6EB1D06D2C1006A3455 /* UIView+WebCacheOperation.h in Headers */,
325312CC200F09910046BF1E /* SDWebImageTransition.h in Headers */,
80377C6D1F2F666400F89830 /* huffman_utils.h in Headers */,
80377C731F2F666400F89830 /* random_utils.h in Headers */,
431BB6EE1D06D2C1006A3455 /* NSData+ImageContentType.h in Headers */,
... ... @@ -2271,6 +2290,7 @@
321E60C31F38E91700405457 /* UIImage+ForceDecode.h in Headers */,
80377E561F2F66A800F89830 /* lossless_common.h in Headers */,
4397D2E91D0DDD8C00BB2784 /* UIImage+WebP.h in Headers */,
325312CD200F09910046BF1E /* SDWebImageTransition.h in Headers */,
4397D2EA1D0DDD8C00BB2784 /* UIImage+GIF.h in Headers */,
321E60B51F38E90100405457 /* SDWebImageWebPCoder.h in Headers */,
4397D2EB1D0DDD8C00BB2784 /* NSData+ImageContentType.h in Headers */,
... ... @@ -2333,6 +2353,7 @@
80377C2E1F2F666300F89830 /* bit_reader_utils.h in Headers */,
80377C371F2F666300F89830 /* huffman_encode_utils.h in Headers */,
4A2CAE2F1AB4BB7500B6BC39 /* UIImage+MultiFormat.h in Headers */,
325312CA200F09910046BF1E /* SDWebImageTransition.h in Headers */,
323F8C101F38EF770092B609 /* muxi.h in Headers */,
80377EB41F2F66D400F89830 /* vp8li_dec.h in Headers */,
4A2CAE1A1AB4BB6400B6BC39 /* SDWebImageOperation.h in Headers */,
... ... @@ -2373,6 +2394,7 @@
431738BF1CDFC2660008FEB9 /* encode.h in Headers */,
53761316155AD0D5005750A4 /* SDImageCache.h in Headers */,
323F8C0E1F38EF770092B609 /* muxi.h in Headers */,
325312C8200F09910046BF1E /* SDWebImageTransition.h in Headers */,
321E60A21F38E8F600405457 /* SDWebImageGIFCoder.h in Headers */,
5D5B9142188EE8DD006D06BD /* NSData+ImageContentType.h in Headers */,
80377BFE1F2F665300F89830 /* color_cache_utils.h in Headers */,
... ... @@ -2722,6 +2744,7 @@
323F8B991F38EF770092B609 /* near_lossless_enc.c in Sources */,
80377DE81F2F66A700F89830 /* yuv_mips_dsp_r2.c in Sources */,
80377EC31F2F66D500F89830 /* vp8l_dec.c in Sources */,
325312D1200F09910046BF1E /* SDWebImageTransition.m in Sources */,
321E609D1F38E8ED00405457 /* SDWebImageImageIOCoder.m in Sources */,
323F8B9F1F38EF770092B609 /* picture_csp_enc.c in Sources */,
43C892A31D9D6DDD0022038D /* demux.c in Sources */,
... ... @@ -2883,6 +2906,7 @@
323F8B451F38EF770092B609 /* analysis_enc.c in Sources */,
80377C261F2F666300F89830 /* rescaler_utils.c in Sources */,
323F8BBB1F38EF770092B609 /* predictor_enc.c in Sources */,
325312CF200F09910046BF1E /* SDWebImageTransition.m in Sources */,
80377D2F1F2F66A700F89830 /* dec_msa.c in Sources */,
323F8C151F38EF770092B609 /* muxinternal.c in Sources */,
80377D571F2F66A700F89830 /* rescaler_sse2.c in Sources */,
... ... @@ -3026,6 +3050,7 @@
80377C6A1F2F666400F89830 /* huffman_encode_utils.c in Sources */,
323F8B481F38EF770092B609 /* analysis_enc.c in Sources */,
80377DFE1F2F66A800F89830 /* dec_msa.c in Sources */,
325312D2200F09910046BF1E /* SDWebImageTransition.m in Sources */,
323F8BBE1F38EF770092B609 /* predictor_enc.c in Sources */,
80377E261F2F66A800F89830 /* rescaler_sse2.c in Sources */,
323F8C181F38EF770092B609 /* muxinternal.c in Sources */,
... ... @@ -3214,6 +3239,7 @@
43A918701D8308FE00B3925F /* SDImageCacheConfig.m in Sources */,
80377E4B1F2F66A800F89830 /* enc_mips32.c in Sources */,
4397D2AB1D0DDD8C00BB2784 /* UIView+WebCacheOperation.m in Sources */,
325312D3200F09910046BF1E /* SDWebImageTransition.m in Sources */,
80377E391F2F66A800F89830 /* argb.c in Sources */,
4369C2831D9807EC007E863A /* UIView+WebCache.m in Sources */,
80377E611F2F66A800F89830 /* lossless_sse2.c in Sources */,
... ... @@ -3300,6 +3326,7 @@
323F8B981F38EF770092B609 /* near_lossless_enc.c in Sources */,
80377D6F1F2F66A700F89830 /* cost.c in Sources */,
80377EB31F2F66D400F89830 /* vp8l_dec.c in Sources */,
325312D0200F09910046BF1E /* SDWebImageTransition.m in Sources */,
321E609C1F38E8ED00405457 /* SDWebImageImageIOCoder.m in Sources */,
323F8B9E1F38EF770092B609 /* picture_csp_enc.c in Sources */,
80377D9E1F2F66A700F89830 /* upsampling_mips_dsp_r2.c in Sources */,
... ... @@ -3447,6 +3474,7 @@
80377CE51F2F66A100F89830 /* cost.c in Sources */,
80377E931F2F66D000F89830 /* vp8l_dec.c in Sources */,
321E609A1F38E8ED00405457 /* SDWebImageImageIOCoder.m in Sources */,
325312CE200F09910046BF1E /* SDWebImageTransition.m in Sources */,
323F8B9C1F38EF770092B609 /* picture_csp_enc.c in Sources */,
80377D141F2F66A100F89830 /* upsampling_mips_dsp_r2.c in Sources */,
80377D191F2F66A100F89830 /* yuv_mips_dsp_r2.c in Sources */,
... ...
... ... @@ -111,7 +111,11 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
/**
* By default, when the cache missed, the image is download from the network. This flag can prevent network to load from cache only.
*/
SDWebImageFromCacheOnly = 1 << 15
SDWebImageFromCacheOnly = 1 << 15,
/**
* By default, when you use `SDWebImageTransition` to do some view transition after the image load finished, this transition is only applied for image download from the network. This mask can force to apply view transition for memory and disk cache as well.
*/
SDWebImageForceTransition = 1 << 16
};
typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
... ...
/*
* 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 "SDWebImageCompat.h"
#if SD_UIKIT || SD_MAC
#import "SDImageCache.h"
// for UIKit(iOS & tvOS), we use `+[UIView transitionWithView:duration:options:animations:completion]` for transition animations.
// for AppKit(macOS), we use `+[NSAnimationContext runAnimationGroup:completionHandler:]` for transition animations. You can call `+[NSAnimationContext currentContext]` to grab the context during animations block.
// These transition are provided for basic usage. If you need complicated animation, consider to directly use Core Animation or use `SDWebImageAvoidAutoSetImage` and implement your own after image load finished.
#if SD_UIKIT
typedef UIViewAnimationOptions SDWebImageAnimationOptions;
#else
typedef NS_OPTIONS(NSUInteger, SDWebImageAnimationOptions) {
SDWebImageAnimationOptionAllowsImplicitAnimation = 1 << 0, // specify `allowsImplicitAnimation` for the `NSAnimationContext`
};
#endif
typedef void (^SDWebImageTransitionPreparesBlock)(__kindof UIView * _Nonnull view, UIImage * _Nullable image, NSData * _Nullable imageData, SDImageCacheType cacheType, NSURL * _Nullable imageURL);
typedef void (^SDWebImageTransitionAnimationsBlock)(__kindof UIView * _Nonnull view, UIImage * _Nullable image);
typedef void (^SDWebImageTransitionCompletionBlock)(BOOL finished);
@interface SDWebImageTransition : NSObject
/**
By default, we set the image to the view at the beginning of the animtions. You can disable this and provide custom set image process
*/
@property (nonatomic, assign) BOOL avoidAutoSetImage;
/**
The duration of the transition animation, measured in seconds. Defaults to 0.5.
*/
@property (nonatomic, assign) NSTimeInterval duration;
/**
The timing function used for all animations within this transition animation (macOS).
*/
@property (nonatomic, strong, nullable) CAMediaTimingFunction *timingFunction NS_AVAILABLE_MAC(10_7);
/**
A mask of options indicating how you want to perform the animations.
*/
@property (nonatomic, assign) SDWebImageAnimationOptions animationOptions;
/**
A block object to be executed before the animation sequence starts.
*/
@property (nonatomic, copy, nullable) SDWebImageTransitionPreparesBlock prepares;
/**
A block object that contains the changes you want to make to the specified view.
*/
@property (nonatomic, copy, nullable) SDWebImageTransitionAnimationsBlock animations;
/**
A block object to be executed when the animation sequence ends.
*/
@property (nonatomic, copy, nullable) SDWebImageTransitionCompletionBlock completion;
@end
// Convenience way to use transition. Remember to specify the duration
// for UIKit, these transition just use the correspond `animationOptions`
// for AppKit, these transition use Core Animation in `animations`. So your view must be layer-backed. Set `wantsLayer = YES` before you apply it.
@interface SDWebImageTransition (Conveniences)
// class property is available in Xcode 8. We will drop the Xcode 7.3 support in 5.x
#if __has_feature(objc_class_property)
/// Fade transition.
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *fadeTransition;
/// Flip from left transition.
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromLeftTransition;
/// Flip from right transition.
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromRightTransition;
/// Flip from top transition.
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromTopTransition;
/// Flip from bottom transition.
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromBottomTransition;
/// Curl up transition.
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *curlUpTransition;
/// Curl down transition.
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *curlDownTransition;
#else
+ (nonnull instancetype)fadeTransition;
+ (nonnull instancetype)flipFromLeftTransition;
+ (nonnull instancetype)flipFromRightTransition;
+ (nonnull instancetype)flipFromTopTransition;
+ (nonnull instancetype)flipFromBottomTransition;
+ (nonnull instancetype)curlUpTransition;
+ (nonnull instancetype)curlDownTransition;
#endif
@end
#endif
... ...
/*
* 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 "SDWebImageTransition.h"
#if SD_UIKIT || SD_MAC
#if SD_MAC
#import <QuartzCore/QuartzCore.h>
#endif
@implementation SDWebImageTransition
- (instancetype)init {
self = [super init];
if (self) {
self.duration = 0.5;
}
return self;
}
@end
@implementation SDWebImageTransition (Conveniences)
+ (SDWebImageTransition *)fadeTransition {
SDWebImageTransition *transition = [SDWebImageTransition new];
#if SD_UIKIT
transition.animationOptions = UIViewAnimationOptionTransitionCrossDissolve;
#else
transition.animations = ^(__kindof NSView * _Nonnull view, NSImage * _Nullable image) {
CATransition *trans = [CATransition animation];
trans.type = kCATransitionFade;
[view.layer addAnimation:trans forKey:kCATransition];
};
#endif
return transition;
}
+ (SDWebImageTransition *)flipFromLeftTransition {
SDWebImageTransition *transition = [SDWebImageTransition new];
#if SD_UIKIT
transition.animationOptions = UIViewAnimationOptionTransitionFlipFromLeft;
#else
transition.animations = ^(__kindof NSView * _Nonnull view, NSImage * _Nullable image) {
CATransition *trans = [CATransition animation];
trans.type = kCATransitionPush;
trans.subtype = kCATransitionFromLeft;
[view.layer addAnimation:trans forKey:kCATransition];
};
#endif
return transition;
}
+ (SDWebImageTransition *)flipFromRightTransition {
SDWebImageTransition *transition = [SDWebImageTransition new];
#if SD_UIKIT
transition.animationOptions = UIViewAnimationOptionTransitionFlipFromRight;
#else
transition.animations = ^(__kindof NSView * _Nonnull view, NSImage * _Nullable image) {
CATransition *trans = [CATransition animation];
trans.type = kCATransitionPush;
trans.subtype = kCATransitionFromRight;
[view.layer addAnimation:trans forKey:kCATransition];
};
#endif
return transition;
}
+ (SDWebImageTransition *)flipFromTopTransition {
SDWebImageTransition *transition = [SDWebImageTransition new];
#if SD_UIKIT
transition.animationOptions = UIViewAnimationOptionTransitionFlipFromTop;
#else
transition.animations = ^(__kindof NSView * _Nonnull view, NSImage * _Nullable image) {
CATransition *trans = [CATransition animation];
trans.type = kCATransitionPush;
trans.subtype = kCATransitionFromTop;
[view.layer addAnimation:trans forKey:kCATransition];
};
#endif
return transition;
}
+ (SDWebImageTransition *)flipFromBottomTransition {
SDWebImageTransition *transition = [SDWebImageTransition new];
#if SD_UIKIT
transition.animationOptions = UIViewAnimationOptionTransitionFlipFromBottom;
#else
transition.animations = ^(__kindof NSView * _Nonnull view, NSImage * _Nullable image) {
CATransition *trans = [CATransition animation];
trans.type = kCATransitionPush;
trans.subtype = kCATransitionFromBottom;
[view.layer addAnimation:trans forKey:kCATransition];
};
#endif
return transition;
}
+ (SDWebImageTransition *)curlUpTransition {
SDWebImageTransition *transition = [SDWebImageTransition new];
#if SD_UIKIT
transition.animationOptions = UIViewAnimationOptionTransitionCurlUp;
#else
transition.animations = ^(__kindof NSView * _Nonnull view, NSImage * _Nullable image) {
CATransition *trans = [CATransition animation];
trans.type = kCATransitionReveal;
trans.subtype = kCATransitionFromTop;
[view.layer addAnimation:trans forKey:kCATransition];
};
#endif
return transition;
}
+ (SDWebImageTransition *)curlDownTransition {
SDWebImageTransition *transition = [SDWebImageTransition new];
#if SD_UIKIT
transition.animationOptions = UIViewAnimationOptionTransitionCurlDown;
#else
transition.animations = ^(__kindof NSView * _Nonnull view, NSImage * _Nullable image) {
CATransition *trans = [CATransition animation];
trans.type = kCATransitionReveal;
trans.subtype = kCATransitionFromBottom;
[view.layer addAnimation:trans forKey:kCATransition];
};
#endif
return transition;
}
@end
#endif
... ...
... ... @@ -11,6 +11,7 @@
#if SD_UIKIT || SD_MAC
#import "SDWebImageManager.h"
#import "SDWebImageTransition.h"
/**
A Dispatch group to maintain setImageBlock and completionBlock. This key should be used only internally and may be changed in the future. (dispatch_group_t)
... ... @@ -97,13 +98,21 @@ typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable ima
setImageBlock:(nullable SDSetImageBlock)setImageBlock
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDExternalCompletionBlock)completedBlock
context:(nullable NSDictionary *)context;
context:(nullable NSDictionary<NSString *, id> *)context;
/**
* Cancel the current image load
*/
- (void)sd_cancelCurrentImageLoad;
#pragma mark - Image Transition
/**
The image transition when image load finished. See `SDWebImageTransition`.
If you specify nil, do not do transition. Defautls to nil.
*/
@property (nonatomic, strong, nullable) SDWebImageTransition *sd_imageTransition;
#if SD_UIKIT
#pragma mark - Activity indicator
... ...
... ... @@ -62,7 +62,7 @@ static char TAG_ACTIVITY_SHOW;
setImageBlock:(nullable SDSetImageBlock)setImageBlock
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
completed:(nullable SDExternalCompletionBlock)completedBlock
context:(nullable NSDictionary *)context {
context:(nullable NSDictionary<NSString *, id> *)context {
NSString *validOperationKey = operationKey ?: NSStringFromClass([self class]);
[self sd_cancelImageLoadOperationWithKey:validOperationKey];
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
... ... @@ -144,11 +144,16 @@ static char TAG_ACTIVITY_SHOW;
targetData = nil;
}
// check whether we should use the image transition
SDWebImageTransition *transition = nil;
if (finished && (options & SDWebImageForceTransition || cacheType == SDImageCacheTypeNone)) {
transition = sself.sd_imageTransition;
}
if ([context valueForKey:SDWebImageInternalSetImageGroupKey]) {
dispatch_group_t group = [context valueForKey:SDWebImageInternalSetImageGroupKey];
dispatch_group_enter(group);
dispatch_main_async_safe(^{
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL];
});
// ensure completion block is called after custom setImage process finish
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
... ... @@ -156,7 +161,7 @@ static char TAG_ACTIVITY_SHOW;
});
} else {
dispatch_main_async_safe(^{
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
[sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL];
callCompletedBlockClojure();
});
}
... ... @@ -178,24 +183,79 @@ static char TAG_ACTIVITY_SHOW;
}
- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock {
[self sd_setImage:image imageData:imageData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:nil cacheType:0 imageURL:nil];
}
- (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) {
setImageBlock(image, imageData);
return;
finalSetImageBlock = setImageBlock;
}
#if SD_UIKIT || SD_MAC
if ([self isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)self;
imageView.image = image;
else if ([view isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)view;
finalSetImageBlock = ^(UIImage *tempImage, NSData *tempData) {
imageView.image = image;
};
}
#endif
#if SD_UIKIT
if ([self isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)self;
[button setImage:image forState:UIControlStateNormal];
else if ([view isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)view;
finalSetImageBlock = ^(UIImage *tempImage, NSData *tempData){
[button setImage:image forState:UIControlStateNormal];
};
}
#endif
if (transition) {
#if SD_UIKIT
[UIView transitionWithView:view duration:0 options:0 animations:^{
// 0 duration to let UIKit render placeholder and prepares block
if (transition.prepares) {
transition.prepares(view, image, imageData, cacheType, imageURL);
}
} completion:^(BOOL finished) {
[UIView transitionWithView:view duration:transition.duration options:transition.animationOptions animations:^{
if (finalSetImageBlock && !transition.avoidAutoSetImage) {
finalSetImageBlock(image, imageData);
}
if (transition.animations) {
transition.animations(view, image);
}
} completion:transition.completion];
}];
#elif SD_MAC
[NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull prepareContext) {
// 0 duration to let AppKit render placeholder and prepares block
prepareContext.duration = 0;
if (transition.prepares) {
transition.prepares(view, image, imageData, cacheType, imageURL);
}
} completionHandler:^{
[NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
context.duration = transition.duration;
context.timingFunction = transition.timingFunction;
context.allowsImplicitAnimation = (transition.animationOptions & SDWebImageAnimationOptionAllowsImplicitAnimation);
if (finalSetImageBlock && !transition.avoidAutoSetImage) {
finalSetImageBlock(image, imageData);
}
if (transition.animations) {
transition.animations(view, image);
}
} completionHandler:^{
if (transition.completion) {
transition.completion(YES);
}
}];
}];
#endif
} else {
if (finalSetImageBlock) {
finalSetImageBlock(image, imageData);
}
}
}
- (void)sd_setNeedsLayout {
... ... @@ -206,6 +266,15 @@ static char TAG_ACTIVITY_SHOW;
#endif
}
#pragma mark - Image Transition
- (SDWebImageTransition *)sd_imageTransition {
return objc_getAssociatedObject(self, @selector(sd_imageTransition));
}
- (void)setSd_imageTransition:(SDWebImageTransition *)sd_imageTransition {
objc_setAssociatedObject(self, @selector(sd_imageTransition), sd_imageTransition, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#pragma mark - Activity indicator
#pragma mark -
... ...
... ... @@ -34,6 +34,7 @@ FOUNDATION_EXPORT const unsigned char WebImageVersionString[];
#import <SDWebImage/UIImage+MultiFormat.h>
#import <SDWebImage/SDWebImageOperation.h>
#import <SDWebImage/SDWebImageDownloader.h>
#import <SDWebImage/SDWebImageTransition.h>
#if SD_MAC || SD_UIKIT
#import <SDWebImage/MKAnnotationView+WebCache.h>
... ...