线性重复动画

简介:

线性重复动画

 

效果

 

说明

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

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的相关动画会在进入后台的时候自动移除掉了,所以,从后台进入前台的时候需要手动开启动画:

以下是核心所在:

目录
相关文章
寻找旋转排序数组中的最小值 (重复与非重复代码)
寻找旋转排序数组中的最小值 (重复与非重复代码)
121 0
寻找旋转排序数组中的最小值 (重复与非重复代码)
|
9月前
|
JavaScript Serverless
Vue 封装一个函数,小球原始高度不固定,弹起比例不固定、计算谈几次后,高度低于1米
Vue 封装一个函数,小球原始高度不固定,弹起比例不固定、计算谈几次后,高度低于1米
35 1
|
9月前
|
算法 测试技术 C#
【滑动窗口】【差分数组】C++算法:K 连续位的最小翻转次数
【滑动窗口】【差分数组】C++算法:K 连续位的最小翻转次数
封装一个函数,小球原始高度不固定,弹起比例不固定、计算谈几次后,高度低于1米
封装一个函数,小球原始高度不固定,弹起比例不固定、计算谈几次后,高度低于1米
66 0
|
前端开发 算法 JavaScript
【前端算法】将一个数组旋转K步
使用typescript完成将一个数组旋转K步的过程
110 0
|
前端开发 算法
canvas进阶——实现连续平滑的曲线
前言 大家好,我是Fly, canvas真是个强大的东西,每天沉迷这个无法自拔, 可以做游戏,可以对图片处理,后面会给大家分享一篇,canvas实现两张图片找不同的功能, 听着是不是挺有意思的, 有点像游戏 「找你妹」,但是这都不是本篇文章想要表达的重点,读完今天这篇文章,你可以学到什么呢 「Canvas」 实现一个简单的画版小工具 「Canvas」 画出平滑的曲线, 这是本篇文章的重点 这时候有人问我她??, 我的心里没有她的,只有你们「coder」, 下面一起学习吧,预计阅读5分钟。 canvas实现一个画版小工具 因为也比较简单,我大概说下思路: 首先我对canvas 画布坚监听3
canvas进阶——实现连续平滑的曲线
|
索引
【编程练习】3*3 的矩阵,值限定为1-9不重复,已知横竖的和,和一个斜着的值,求这个矩阵
 x     x     x 11 x     x     x 15 x     x     x 19 16  14   15 15 讨论贴: http://bbs.csdn.net/topics/391816265 先求横竖斜三行的精确匹配方法: // puzzl.cpp : 定义控制台应用程序的入口点。
804 0

热门文章

最新文章