动画控制属性

duration

duration:对将要进行的动画的一次迭代指定了时间;

repeatCount

repeatCount:代表动画重复的迭代次数。如果duration是2,repeatCount设为3.5(三个半迭代),那么完整的动画时长将是7秒;

duration和repeatCount默认都是0。但这不意味着动画时长为0秒,或者0次,这里的0仅仅代表了“默认”,也就是0.25秒和1次

autoreverses

自动(返回)动画

repeatDuration

创建重复动画的另一种方式是使用repeatDuration属性,它让动画重复一个指定的时间,而不是指定次数。你甚至设置一个叫做 autoreverses的属性(BOOL类型)在每次间隔交替循环过程中自动回放。这对于播放一段连续非循环的动画很有用,例如打开一扇门,然后关上它 (图9.2)。

9.2.jpeg

对门进行摆动的代码见清单9.2。我们用了autoreverses来使门在打开后自动关闭,在这里我们把repeatDuration设置为 INFINITY,于是动画无限循环播放,设置repeatCount为INFINITY也有同样的效果。注意repeatCount和 repeatDuration可能会相互冲突,所以你只要对其中一个指定非零值。对两个属性都设置非0值的行为没有被定义。

清单9.2 使用autoreverses属性实现门的摇摆

@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
//add the door
    CALayer *doorLayer = [CALayer layer];
    doorLayer.frame = CGRectMake(0, 0, 128, 256);
    doorLayer.position = self.view.center;
    doorLayer.anchorPoint = CGPointMake(0, 0.5);
    doorLayer.contents = (__bridge id)[UIImage imageNamed: @"bjl_list_02"].CGImage;
    [self.view.layer addSublayer:doorLayer];
    //apply perspective transform
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1.0 / 500.0;
    self.view.layer.sublayerTransform = perspective;
    //apply swinging animation
    CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"transform.rotation.y";
    animation.toValue = @(-M_PI_2);
    animation.duration = 1;
    //animation.repeatDuration = INFINITY;
    animation.autoreverses = YES;
    [doorLayer addAnimation:animation forKey:nil];
}
@end

beginTime

beginTime:指定了动画开始之前的的延迟时间。这里的延迟从动画添加到可见图层的那一刻开始测量,默认是0(就是说动画会立刻执行),然而在层级关系中,beginTime指定了父图层开始动画(或 者组合关系中的父动画)和对象将要开始自己动画之间的偏移

speed

speed:是一个时间的倍数,默认1.0,减少它会减慢图层/动画的时间,增加它会加快速度。如果2.0的速度,那么对于一个duration为1的动画,实际上在0.5秒的时候就已经完成了;

timeOffset

timeOffset:和beginTime类似,但是和增加beginTime导致的延迟动画不同,增加timeOffset只是让动画快进到某一点,例如,对于一个持续1秒的动画来说,设置timeOffset为0.5意味着动画将从一半的地方开始。和beginTime不同的是,timeOffset并不受speed的影响。

避免在动画结束的时候急速返回提供另一种方案:

@interface ViewController ()<CAMediaTiming>
{
    CALayer *doorLayer;
}
@end

@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    doorLayer = [CALayer layer];
    doorLayer.frame = CGRectMake(0, 0, 128, 256);
    doorLayer.position = self.view.center;
    doorLayer.anchorPoint = CGPointMake(0, 0.5);
    doorLayer.contents = (__bridge id)[UIImage imageNamed: @"bjl_list_02"].CGImage;
    [self.view.layer addSublayer:doorLayer];
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1.0 / 500.0;
    self.view.layer.sublayerTransform = perspective;
    
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{

    //add the door
    
    
    //apply perspective transform

    //apply swinging animation
    CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"transform.rotation.y";
    animation.byValue = @(-M_PI_4);
    animation.duration = 1;
    animation.fillMode=kCAFillModeBoth;
    animation.removedOnCompletion=NO;
    
    //animation.repeatDuration = INFINITY;
    [doorLayer addAnimation:animation forKey:nil];
}

fillMode

四种常量:

kCAFillModeForwards 

kCAFillModeBackwards 

kCAFillModeBoth 

kCAFillModeRemoved

默认是kCAFillModeRemoved.但是记住了,当用它来解决这个问题的时候,需要把removeOnCompletion设置为NO,另外需要给动画添加一个非空的键,于是可以在不需要动画的时候把它从图层上移除。

层级关系时间

对CALayer或者CAGroupAnimation调整duration和repeatCount/repeatDuration属性并不会影响到子 动画。但是beginTime,timeOffset和speed属性将会影响到子动画。然而在层级关系中,beginTime指定了父图层开始动画(或 者组合关系中的父动画)和对象将要开始自己动画之间的偏移。类似的,调整CALayer和CAGroupAnimation的speed属性将会对动画以 及子动画速度应用一个缩放的因子。

原文地址:https://www.cnblogs.com/jingdizhiwa/p/5508217.html