iOS DIY AnimatedImags
ASImageNode 源码阅读笔记 1
动画形式播放images 系统的自己有 UIImageView ,通过 animationImages 来播放动画,并且有
animationDuration 播放时长
animationRepeatCount 播放次数
- (void)startAnimating; 开始播放
- (void)stopAnimating; 停止播放
属性和方法控制动画相关的一些事情。
但是如果,系统的不能满足需求了,就需要DIY 一个自己能用的。比如,images 的某一个动画过程添加对UIImageView 的动画,或者外部回调。
因为跟动画帧相关并且每一帧之间的时差是有要求的,我们就要考虑使用计时器了,
iOS 中,目前有两个可以选择 NSTimer 和 CADisplayLink,因为 CADisplayLink 是和屏幕渲染挂钩的,并且可靠性,准时性比较高,因此我们选择 CADisplayLink。
_displayLink = [CADisplayLink displayLinkWithTarget:[ASWeakProxy weakProxyWithTarget:self] selector:@selector(displayLinkFired:)];
_displayLink.frameInterval = self.animatedImage.frameInterval;
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:_animatedImageRunLoopMode];
用法也比较简单。
AsyncDisplayKit 里面也有提供一个好用的,众所周知 AsyncDisplayKit 以性能著称的,多研究有益身心……
具体实现在
ASImageNode+AnimatedImage.mm
相关声明在
#import "ASImageNode+AnimatedImagePrivate.h"
extern NSString *const ASAnimatedImageDefaultRunLoopMode;
@interface ASImageNode ()
{
//images 对象,遵循 ASAnimatedImageProtocol 协议
id <ASAnimatedImageProtocol> _animatedImage;
//是否暂停
BOOL _animatedImagePaused;
//runloop
NSString *_animatedImageRunLoopMode;
///定时器
CADisplayLink *_displayLink;
CFTimeInterval _playHead;
NSUInteger _playedLoops;
}
@end
通过声明就可以简单看出实现原理了。实现原理无非就是在定时器函数里替换图片。有兴趣的可以查阅源码,
细节
使用 ASDisplayNodeAssertMainThread(); 确保动画先关函数在主线程进行。
使用 ASWeakProxy 包装 target ,防止循环引用,从而内存泄漏。YYKit 中也有同样的类。