源码阅读:SDWebImage(十六)——SDWebImageTransition

1,595 阅读3分钟

该文章阅读的SDWebImage的版本为4.3.3。

该类是负责图像加载完成后在控件上的展示动画。

1.公共类型定义

/**
 定义动画选项
 */
typedef UIViewAnimationOptions SDWebImageAnimationOptions;
/**
 用于动画开始之前要执行的代码块
 */
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);

2.公共属性

/**
 默认情况下,我们将图像设置为动画开头的视图。可以选择禁用此功能并提供自定义设置图像处理方法
 */
@property (nonatomic, assign) BOOL avoidAutoSetImage;
/**
 动画的持续时间,以秒为单位。 默认为0.5秒。
 */
@property (nonatomic, assign) NSTimeInterval duration;
/**
 用于macOS上的计时功能
 */
@property (nonatomic, strong, nullable) CAMediaTimingFunction *timingFunction NS_AVAILABLE_MAC(10_7);
/**
 动画选项
 */
@property (nonatomic, assign) SDWebImageAnimationOptions animationOptions;
/**
 动画开始前所要执行的代码块
 */
@property (nonatomic, copy, nullable) SDWebImageTransitionPreparesBlock prepares;
/**
 动画代码块
 */
@property (nonatomic, copy, nullable) SDWebImageTransitionAnimationsBlock animations;
/**
 动画结束后所要执行的代码块
 */
@property (nonatomic, copy, nullable) SDWebImageTransitionCompletionBlock completion;

3.Conveniences分类

这个分类用于快速创建动画。

3.1. 公共属性

调用不同的类属性获取不同的动画效果

@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *fadeTransition;
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromLeftTransition;
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromRightTransition;
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromTopTransition;
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *flipFromBottomTransition;
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *curlUpTransition;
@property (nonatomic, class, nonnull, readonly) SDWebImageTransition *curlDownTransition;

3.2.公共方法

如果类属性不可用,就调用类方法类获取不同的动画效果

+ (nonnull instancetype)fadeTransition;
+ (nonnull instancetype)flipFromLeftTransition;
+ (nonnull instancetype)flipFromRightTransition;
+ (nonnull instancetype)flipFromTopTransition;
+ (nonnull instancetype)flipFromBottomTransition;
+ (nonnull instancetype)curlUpTransition;
+ (nonnull instancetype)curlDownTransition;

3.3.实现

创建不同的动画并兼容macOS

+ (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;
}

4.实现

实现中只做做了在初始化方法中设置默认展示时间为0.5秒

- (instancetype)init {
    self = [super init];
    if (self) {
        self.duration = 0.5;
    }
    return self;
}

5.总结

这个类的总结也没啥好说的,就是帮助创建动画的类。

值得说的一点是,有一个属性关键字class,是Xcode 8中添加的,我对这个关键字的理解是:这个关键字用于声明一个“类属性”,平常我们声明的都是“对象属性”,可以类比于“类方法”和“对象方法”的关系进行理解。使用了这个关键字的属性,需要声明静态变量保存,需要手写getter和setter。在使用时,这个类属性相当于一个类内的静态全局变量,也可以类比成一个单例对象的对象属性,即这个类属性在这个类内是共享的。想要了解更多可以看这篇文章:Swift 3.0 令人兴奋,但Objective-C也有小改进--Objective-C的类属性

源码阅读系列:SDWebImage

源码阅读:SDWebImage(一)——从使用入手

源码阅读:SDWebImage(二)——SDWebImageCompat

源码阅读:SDWebImage(三)——NSData+ImageContentType

源码阅读:SDWebImage(四)——SDWebImageCoder

源码阅读:SDWebImage(五)——SDWebImageFrame

源码阅读:SDWebImage(六)——SDWebImageCoderHelper

源码阅读:SDWebImage(七)——SDWebImageImageIOCoder

源码阅读:SDWebImage(八)——SDWebImageGIFCoder

源码阅读:SDWebImage(九)——SDWebImageCodersManager

源码阅读:SDWebImage(十)——SDImageCacheConfig

源码阅读:SDWebImage(十一)——SDImageCache

源码阅读:SDWebImage(十二)——SDWebImageDownloaderOperation

源码阅读:SDWebImage(十三)——SDWebImageDownloader

源码阅读:SDWebImage(十四)——SDWebImageManager

源码阅读:SDWebImage(十五)——SDWebImagePrefetcher

源码阅读:SDWebImage(十六)——SDWebImageTransition

源码阅读:SDWebImage(十七)——UIView+WebCacheOperation

源码阅读:SDWebImage(十八)——UIView+WebCache

源码阅读:SDWebImage(十九)——UIImage+ForceDecode/UIImage+GIF/UIImage+MultiFormat

源码阅读:SDWebImage(二十)——UIButton+WebCache

源码阅读:SDWebImage(二十一)——UIImageView+WebCache/UIImageView+HighlightedWebCache