zoukankan      html  css  js  c++  java
  • 线性重复动画

    线性重复动画

    效果

    说明

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

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

    以下是核心所在:

  • 相关阅读:
    hadoop编程问题
    poj2760:数字三角形
    poj1201:Intervals
    差分约束
    poj1033:Defragment
    poj1089:Intervals
    poj2251:Dungeon Master
    天天向上的力量 III
    整数逆位运算
    星号三角形 I
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/5381717.html
Copyright © 2011-2022 走看看