你的位置:首页 > 操作系统

[操作系统]线性重复动画


线性重复动画

 

效果

 

说明

线性重复的动画可以用在以下的一些场景:

1)线性加载效果(如上图)

2)下载箭头的循环出现

 

源码

https://github.com/YouXianMing/Animations

//// ReplicatorLineAnimationView.h// Animations//// Created by YouXianMing on 16/4/12.// Copyright © 2016年 YouXianMing. All rights reserved.//#import <UIKit/UIKit.h>typedef enum : NSUInteger {    kReplicatorLeft,  kReplicatorRight,  kReplicatorUp,  kReplicatorDown  } EReplicatorLineDirection;@interface ReplicatorLineAnimationView : UIView/** * Animation's direction. */@property (nonatomic) EReplicatorLineDirection direction;/** * Animation's speed. */@property (nonatomic) CGFloat      speed;/** * Animation's image. */@property (nonatomic, strong) UIImage *image;/** * Start animation. */- (void)startAnimation;@end

//// ReplicatorLineAnimationView.m// Animations//// Created by YouXianMing on 16/4/12.// Copyright © 2016年 YouXianMing. All rights reserved.//#import "ReplicatorLineAnimationView.h"@interface ReplicatorLineAnimationView () {    CAReplicatorLayer *_replicatorLayer;  CALayer      *_animationLayer;  NSString     *_animationKeyPath;  CGFloat      _animationToValue;  CGFloat      _offsetX;  CGFloat      _offsetY;  CATransform3D   _instanceTransform;  BOOL        _startAnimation;}@end@implementation ReplicatorLineAnimationView- (instancetype)initWithFrame:(CGRect)frame {    if (self = [super initWithFrame:frame]) {        self.speed       = 2.f;    _replicatorLayer    = [CAReplicatorLayer layer];    _replicatorLayer.frame = self.bounds;    [self.layer addSublayer:_replicatorLayer];        _animationLayer    = [CALayer layer];    _animationLayer.frame = self.bounds;    [_replicatorLayer addSublayer:_animationLayer];        self.layer.masksToBounds = YES;        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(eventDidBecomeActive:)                           name:UIApplicationDidBecomeActiveNotification object:nil];  }    return self;}- (void)startAnimation {    _startAnimation = YES;    if (_animationKeyPath.length) {        [_animationLayer removeAnimationForKey:_animationKeyPath];  }    [self dealWithTheEReplicatorLineDirection];    _replicatorLayer.instanceCount   = 2;  _replicatorLayer.instanceTransform = _instanceTransform;  _animationLayer.contents      = (__bridge id _Nullable)(self.image.CGImage);    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:_animationKeyPath];  animation.toValue      = @(_animationToValue);  animation.duration     = 1.f / self.speed;  animation.timingFunction  = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];  animation.repeatCount    = HUGE_VALF;  [_animationLayer addAnimation:animation forKey:_animationKeyPath];}- (void)dealWithTheEReplicatorLineDirection {    if (_direction == kReplicatorLeft || _direction == kReplicatorRight) {        _animationKeyPath = @"position.x";    _offsetX      = _direction == kReplicatorLeft ? self.frame.size.width : -self.frame.size.width;    _offsetY      = 0;    _animationToValue = _animationLayer.position.x - _offsetX;    _instanceTransform = CATransform3DMakeTranslation(_offsetX, 0.0, 0.0);      } else if (_direction == kReplicatorUp || _direction == kReplicatorDown) {        _animationKeyPath = @"position.y";    _offsetX      = 0;    _offsetY      = _direction == kReplicatorUp ? self.frame.size.height : -self.frame.size.height;    _animationToValue = _animationLayer.position.y - _offsetY;    _instanceTransform = CATransform3DMakeTranslation(0.0, _offsetY, 0.0);  }}- (void)dealloc {    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];}- (void)eventDidBecomeActive:(id)obj {    NSNotification *fication = obj;    if ([fication.name isEqualToString:UIApplicationDidBecomeActiveNotification]) {        if (_startAnimation == YES) {            [self startAnimation];    }  }}@end

 

细节

线性重复动画是有着方向性的,他有4个方向可供你使用:

你需要设置方向值、速度值以及一张可以循环显示的图片,对图片也是有要求的,图片的话需要保证平移的时候可以无缝衔接:

CALayer的相关动画会在进入后台的时候自动移除掉了,所以,从后台进入前台的时候需要手动开启动画:

以下是核心所在: