iOS实现模仿时钟左右摆动的动画(核心动画运用)

2017-08-24  本文已影响1289人  Michael1

首先实现往左👈摆动

- (void)startLeftAnnimation{

    /// 左边👈
    //初始化一个动画
    CABasicAnimation *baseAnimation = [CABasicAnimation animation];
    //动画运动的方式,现在指定的是围绕Z轴旋转
    baseAnimation.keyPath = @"transform.rotation.z";
    //动画持续时间
    baseAnimation.duration = 0.5;
    //开始的角度
    baseAnimation.fromValue = [NSNumber numberWithFloat:0];
    //结束的角度
    baseAnimation.toValue = [NSNumber numberWithFloat:M_PI/8];
    //动画的运动方式
    baseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    //是否反向移动动画
    baseAnimation.autoreverses = YES;
    //动画的代理
    baseAnimation.delegate = self;
    //动画结束后的状态
    baseAnimation.fillMode = kCAFillModeForwards;

    [baseAnimation setValue:@"left" forKey:@"left"];

    [self.layer addAnimation:baseAnimation forKey:@"left"];

}

同样的道理实现往右👉摆动

- (void)startRightAnnimation{
    /// 右边👉
    //初始化一个动画
    CABasicAnimation *baseAnimation2 = [CABasicAnimation animation];
    //动画运动的方式,现在指定的是围绕Z轴旋转
    baseAnimation2.keyPath = @"transform.rotation.z";
    //动画持续时间
    baseAnimation2.duration = 0.5;
    //开始的角度
    baseAnimation2.fromValue = [NSNumber numberWithFloat:0];
    //结束的角度
    baseAnimation2.toValue = [NSNumber numberWithFloat:-M_PI/8];
    //动画的运动方式
    baseAnimation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    //是否反向移动动画
    baseAnimation2.autoreverses = YES;
    //动画的代理
    baseAnimation2.delegate = self;
    //动画结束后的状态
    baseAnimation2.fillMode = kCAFillModeForwards;

    [baseAnimation2 setValue:@"right" forKey:@"right"];

    [self.layer addAnimation:baseAnimation2 forKey:@"right"];
}

最后根据在代理方法中实现连续的左右摆动

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {

    if (flag) {

        if ([[anim valueForKey:@"left"] isEqualToString:@"left"]) {
            //检测到左边结束后,开始右边的动画
            [self startRightAnnimation];
        }else if ([[anim valueForKey:@"right"] isEqualToString:@"right"]) {

            self.count++;
            if (self.count <= 2) {

                //检测到右边动画的时候,开始左边的动画
                [self startLeftAnnimation];
            }else {

                if (self.finishBlock) {
                    self.finishBlock();
                }

                /// 移除很重要 要不然不会调用dealloc
                [self.layer removeAllAnimations];

            }
        }
    }
}

本来以为这样就可以就没有问题了,但是测试之后, 大失所望。 是因为我们忘记了最终要的一个anchorPoint(锚点),这是个什么玩意,举个例子,桌子上有一张纸,你用一个手指头按着他,当他不动的时候,他就在那里,不增不减,当你要旋转他的时候,那就要看你按住的那个点的位置。动画中的旋转也是这个样子,这个锚点,决定了你的旋转。

图2.png

在这个图中我们可以看到,默认的锚点是(0.5,0.5),也就是layer的中心位置,锚点的取值范围是0-1 ,当围绕着锚点旋转的时候,不同的锚点,旋转效果是不一样的。

所以我们要设置一下anchorPoint

        // 锚点(0 - 1)
        self.layer.anchorPoint = CGPointMake(0.5, 0);

最终实现的效果(模拟器上边看着不太流畅,真机是没问题的)

图片3.gif
上一篇下一篇

猜你喜欢

热点阅读