diff --git a/SDWebImage.xcodeproj/project.pbxproj b/SDWebImage.xcodeproj/project.pbxproj index bbb554c1..fea55554 100644 --- a/SDWebImage.xcodeproj/project.pbxproj +++ b/SDWebImage.xcodeproj/project.pbxproj @@ -74,6 +74,7 @@ 325312CA200F09910046BF1E /* SDWebImageTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 325312C6200F09910046BF1E /* SDWebImageTransition.h */; settings = {ATTRIBUTES = (Public, ); }; }; 325312CE200F09910046BF1E /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312C7200F09910046BF1E /* SDWebImageTransition.m */; }; 325312D0200F09910046BF1E /* SDWebImageTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312C7200F09910046BF1E /* SDWebImageTransition.m */; }; + 3253F236244982D3006C2BE8 /* SDWebImageTransitionInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3253F235244982D3006C2BE8 /* SDWebImageTransitionInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 32542763235576E20042BAA4 /* SDWebImageDownloaderResponseModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 32542761235576E20042BAA4 /* SDWebImageDownloaderResponseModifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32542764235576E20042BAA4 /* SDWebImageDownloaderResponseModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 32542762235576E20042BAA4 /* SDWebImageDownloaderResponseModifier.m */; }; 32542765235576E20042BAA4 /* SDWebImageDownloaderResponseModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 32542762235576E20042BAA4 /* SDWebImageDownloaderResponseModifier.m */; }; @@ -413,6 +414,7 @@ 3250C9ED2355D9DA0093A896 /* SDWebImageDownloaderDecryptor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderDecryptor.m; path = Core/SDWebImageDownloaderDecryptor.m; sourceTree = ""; }; 325312C6200F09910046BF1E /* SDWebImageTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDWebImageTransition.h; path = Core/SDWebImageTransition.h; sourceTree = ""; }; 325312C7200F09910046BF1E /* SDWebImageTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDWebImageTransition.m; path = Core/SDWebImageTransition.m; sourceTree = ""; }; + 3253F235244982D3006C2BE8 /* SDWebImageTransitionInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTransitionInternal.h; sourceTree = ""; }; 32542761235576E20042BAA4 /* SDWebImageDownloaderResponseModifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDWebImageDownloaderResponseModifier.h; path = Core/SDWebImageDownloaderResponseModifier.h; sourceTree = ""; }; 32542762235576E20042BAA4 /* SDWebImageDownloaderResponseModifier.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDWebImageDownloaderResponseModifier.m; path = Core/SDWebImageDownloaderResponseModifier.m; sourceTree = ""; }; 3257EAF721898AED0097B271 /* SDImageGraphics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SDImageGraphics.h; path = Core/SDImageGraphics.h; sourceTree = ""; }; @@ -659,6 +661,7 @@ 325C460D223394D8004CAE11 /* SDImageCachesManagerOperation.m */, 32C78E39233371AD00C6B7F8 /* SDImageIOAnimatedCoderInternal.h */, 32986560233737C70071958B /* SDImageHEICCoderInternal.h */, + 3253F235244982D3006C2BE8 /* SDWebImageTransitionInternal.h */, 325C461E2233A02E004CAE11 /* UIColor+SDHexString.h */, 325C461F2233A02E004CAE11 /* UIColor+SDHexString.m */, 325C46242233A0A8004CAE11 /* NSBezierPath+SDRoundedCorners.h */, @@ -883,6 +886,7 @@ 328BB6AC2081FEE500760D6C /* SDWebImageCacheSerializer.h in Headers */, 325F7CCA238942AB00AEDFCC /* UIImage+ExtendedCacheData.h in Headers */, 325C46272233A0A8004CAE11 /* NSBezierPath+SDRoundedCorners.h in Headers */, + 3253F236244982D3006C2BE8 /* SDWebImageTransitionInternal.h in Headers */, 321B378F2083290E00C0EA77 /* SDImageLoadersManager.h in Headers */, 329A185B1FFF5DFD008C9A2F /* UIImage+Metadata.h in Headers */, 4369C2791D9807EC007E863A /* UIView+WebCache.h in Headers */, diff --git a/SDWebImage/Core/SDWebImageTransition.h b/SDWebImage/Core/SDWebImageTransition.h index ea52b313..5e7a5e04 100644 --- a/SDWebImage/Core/SDWebImageTransition.h +++ b/SDWebImage/Core/SDWebImageTransition.h @@ -15,7 +15,21 @@ typedef UIViewAnimationOptions SDWebImageAnimationOptions; #else typedef NS_OPTIONS(NSUInteger, SDWebImageAnimationOptions) { - SDWebImageAnimationOptionAllowsImplicitAnimation = 1 << 0, // specify `allowsImplicitAnimation` for the `NSAnimationContext` + SDWebImageAnimationOptionAllowsImplicitAnimation = 1 << 0, // specify `allowsImplicitAnimation` for the `NSAnimationContext` + + SDWebImageAnimationOptionCurveEaseInOut = 0 << 16, // default + SDWebImageAnimationOptionCurveEaseIn = 1 << 16, + SDWebImageAnimationOptionCurveEaseOut = 2 << 16, + SDWebImageAnimationOptionCurveLinear = 3 << 16, + + SDWebImageAnimationOptionTransitionNone = 0 << 20, // default + SDWebImageAnimationOptionTransitionFlipFromLeft = 1 << 20, + SDWebImageAnimationOptionTransitionFlipFromRight = 2 << 20, + SDWebImageAnimationOptionTransitionCurlUp = 3 << 20, + SDWebImageAnimationOptionTransitionCurlDown = 4 << 20, + SDWebImageAnimationOptionTransitionCrossDissolve = 5 << 20, + SDWebImageAnimationOptionTransitionFlipFromTop = 6 << 20, + SDWebImageAnimationOptionTransitionFlipFromBottom = 7 << 20, }; #endif @@ -42,7 +56,7 @@ typedef void (^SDWebImageTransitionCompletionBlock)(BOOL finished); /** The timing function used for all animations within this transition animation (macOS). */ -@property (nonatomic, strong, nullable) CAMediaTimingFunction *timingFunction API_UNAVAILABLE(ios, tvos, watchos); +@property (nonatomic, strong, nullable) CAMediaTimingFunction *timingFunction API_UNAVAILABLE(ios, tvos, watchos) API_DEPRECATED("Use SDWebImageAnimationOptions instead, or grab NSAnimationContext.currentContext and modify the timingFunction", macos(10.10, 10.10)); /** A mask of options indicating how you want to perform the animations. */ diff --git a/SDWebImage/Core/SDWebImageTransition.m b/SDWebImage/Core/SDWebImageTransition.m index b04a4c34..b7e379e1 100644 --- a/SDWebImage/Core/SDWebImageTransition.m +++ b/SDWebImage/Core/SDWebImageTransition.m @@ -11,7 +11,62 @@ #if SD_UIKIT || SD_MAC #if SD_MAC -#import +#import "SDWebImageTransitionInternal.h" +#import "SDInternalMacros.h" + +CAMediaTimingFunction * SDTimingFunctionFromAnimationOptions(SDWebImageAnimationOptions options) { + if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveLinear, options)) { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; + } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseIn, options)) { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; + } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseOut, options)) { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; + } else if (SD_OPTIONS_CONTAINS(SDWebImageAnimationOptionCurveEaseInOut, options)) { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + } else { + return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; + } +} + +CATransition * SDTransitionFromAnimationOptions(SDWebImageAnimationOptions options) { + if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCrossDissolve)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionFade; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromLeft)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromLeft; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromRight)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromRight; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromTop)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromTop; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionFlipFromBottom)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromBottom; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCurlUp)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionReveal; + trans.subtype = kCATransitionFromTop; + return trans; + } else if (SD_OPTIONS_CONTAINS(options, SDWebImageAnimationOptionTransitionCurlDown)) { + CATransition *trans = [CATransition animation]; + trans.type = kCATransitionReveal; + trans.subtype = kCATransitionFromBottom; + return trans; + } else { + return nil; + } +} #endif @implementation SDWebImageTransition @@ -33,11 +88,7 @@ #if SD_UIKIT transition.animationOptions = UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction; #else - transition.animations = ^(__kindof NSView * _Nonnull view, NSImage * _Nullable image) { - CATransition *trans = [CATransition animation]; - trans.type = kCATransitionFade; - [view.layer addAnimation:trans forKey:kCATransition]; - }; + transition.animationOptions = SDWebImageAnimationOptionTransitionCrossDissolve; #endif return transition; } @@ -47,12 +98,7 @@ #if SD_UIKIT transition.animationOptions = UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionAllowUserInteraction; #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]; - }; + transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromLeft; #endif return transition; } @@ -62,12 +108,7 @@ #if SD_UIKIT transition.animationOptions = UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionAllowUserInteraction; #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]; - }; + transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromRight; #endif return transition; } @@ -77,12 +118,7 @@ #if SD_UIKIT transition.animationOptions = UIViewAnimationOptionTransitionFlipFromTop | UIViewAnimationOptionAllowUserInteraction; #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]; - }; + transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromTop; #endif return transition; } @@ -92,12 +128,7 @@ #if SD_UIKIT transition.animationOptions = UIViewAnimationOptionTransitionFlipFromBottom | UIViewAnimationOptionAllowUserInteraction; #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]; - }; + transition.animationOptions = SDWebImageAnimationOptionTransitionFlipFromBottom; #endif return transition; } @@ -107,12 +138,7 @@ #if SD_UIKIT transition.animationOptions = UIViewAnimationOptionTransitionCurlUp | UIViewAnimationOptionAllowUserInteraction; #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]; - }; + transition.animationOptions = SDWebImageAnimationOptionTransitionCurlUp; #endif return transition; } @@ -122,12 +148,7 @@ #if SD_UIKIT transition.animationOptions = UIViewAnimationOptionTransitionCurlDown | UIViewAnimationOptionAllowUserInteraction; #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]; - }; + transition.animationOptions = SDWebImageAnimationOptionTransitionCurlDown; #endif return transition; } diff --git a/SDWebImage/Core/UIView+WebCache.m b/SDWebImage/Core/UIView+WebCache.m index 5e9f030a..a000bfa3 100644 --- a/SDWebImage/Core/UIView+WebCache.m +++ b/SDWebImage/Core/UIView+WebCache.m @@ -11,6 +11,7 @@ #import "UIView+WebCacheOperation.h" #import "SDWebImageError.h" #import "SDInternalMacros.h" +#import "SDWebImageTransitionInternal.h" const int64_t SDWebImageProgressUnitCountUnknown = 1LL; @@ -260,11 +261,22 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL; } completionHandler:^{ [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { context.duration = transition.duration; - context.timingFunction = transition.timingFunction; + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + CAMediaTimingFunction *timingFunction = transition.timingFunction; + #pragma clang diagnostic pop + if (!timingFunction) { + timingFunction = SDTimingFunctionFromAnimationOptions(transition.animationOptions); + } + context.timingFunction = timingFunction; context.allowsImplicitAnimation = SD_OPTIONS_CONTAINS(transition.animationOptions, SDWebImageAnimationOptionAllowsImplicitAnimation); if (finalSetImageBlock && !transition.avoidAutoSetImage) { finalSetImageBlock(image, imageData, cacheType, imageURL); } + CATransition *trans = SDTransitionFromAnimationOptions(transition.animationOptions); + if (trans) { + [view.layer addAnimation:trans forKey:kCATransition]; + } if (transition.animations) { transition.animations(view, image); } diff --git a/SDWebImage/Private/SDWebImageTransitionInternal.h b/SDWebImage/Private/SDWebImageTransitionInternal.h new file mode 100644 index 00000000..1b70649a --- /dev/null +++ b/SDWebImage/Private/SDWebImageTransitionInternal.h @@ -0,0 +1,19 @@ +/* +* 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 + +/// Helper method for Core Animation transition +FOUNDATION_EXPORT CAMediaTimingFunction * _Nullable SDTimingFunctionFromAnimationOptions(SDWebImageAnimationOptions options); +FOUNDATION_EXPORT CATransition * _Nullable SDTransitionFromAnimationOptions(SDWebImageAnimationOptions options); + +#endif