IOS核心动画

核心动画

原码:

代码下载请猛戳这里!

核心动画

1.CABasicAnimation:基础动画

- (void)basicAnimation:(CALayer *)layer
{
    //1.创建动画对象
    CABasicAnimation *animation = [CABasicAnimation animation];
    //2.设置动画对象
    /*
        keyPath:决定执行怎样的动画,调整哪个属性来执行动画。
        fromValue:属性值丛什么值开始执行动画。
        toValue:属性值到达什么值结束动画。
        byVale:属性值增加了多少值之后结束动画。
        duration:动画持续时间。

        注意:以下两个属性结合起来用能让图层保持动画结束后的状态。
        removedOnCompletion:执行完动画后是否移除该动画。
        fillMode:动画保持的状态。
            fillMode的作用就是决定当前对象过了非active时间段的行为. 比如动画开始之前,动画结束之后。如果是一个动画CAAnimation,则需要将其removedOnCompletion设置为NO,要不然fillMode不起作用.
            fillMode取值:
                 1.kCAFillModeRemoved: 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态 。
                 2.kCAFillModeForwards: 当动画结束后,layer会一直保持着动画最后的状态
                 3.kCAFillModeBackwards: 这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始.你可以这样设定测试代码,将一个动画加入一个layer的时候延迟5秒执行.然后就会发现在动画没有开始的时候,只要动画被加入了layer,layer便处于动画初始状态
                 4.kCAFillModeBoth: 理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.
     */
    CGFloat tabbar_height = 49;
    switch ([self.layers indexOfObject:layer]) {
        case 0:
            animation.keyPath = @"position";
            animation.fromValue = [NSValue valueWithCGPoint:self.view.center];
            animation.toValue = [NSValue valueWithCGPoint:CGPointMake(Main_Screen_With/3/2, Main_Screen_Height - Main_Screen_With/3/2 - tabbar_height)];
            break;
        case 1:
            animation.keyPath = @"transform.translation.y";
            animation.fromValue = [NSNumber numberWithFloat:0];
            animation.toValue = [NSNumber numberWithFloat:Main_Screen_Height - Main_Screen_With/3 - tabbar_height];
            break;
        case 2:
            animation.keyPath = @"transform.translation";
            animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
            animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, Main_Screen_Height - Main_Screen_With/3 - tabbar_height)];            break;
        case 3:
            animation.keyPath = @"bounds";
            animation.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, Main_Screen_With/3, Main_Screen_With/3)];
            animation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, Main_Screen_With/3, -Main_Screen_With/3/5)];
            break;
        case 4:
            animation.keyPath = @"transform";
            animation.byValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2, 1, 1, 0)];
            break;

        default:
            break;
    }
    animation.duration = 2;
    animation.delegate = self;

    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;

    //3.添加动画
    [layer addAnimation:animation forKey:nil];
}

2.CAKeyframeAnimation:帧动画

- (void)keyFromAnimationInView:(UIView *)view andTapCount:(NSInteger)count
{
    //1.创建动画
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    //2.设置动画属性
    /*
        values:指明整个动画过程中的关键帧点,需要注意的是,起点必须作为values的第一个值。

        keyTimes:该属性是一个数组,用以指定每个子路径(AB,BC,CD)的时间。如果你没有显式地对keyTimes进行设置,则系统会默认每条子路径的时间为:ti=duration/(5-1),即每条子路径的duration相等,都为duration的1\4。当然,我们也可以传个数组让物体快慢结合。例如,你可以传入{0.0, 0.1,0.6,0.7,1.0},其中首尾必须分别是0和1,因此tAB=0.1-0, tCB=0.6-0.1, tDC=0.7-0.6, tED=1-0.7.....

        path:动画运动的路径。

        repeatCount:动画重复次数。

        timingFunctions:这个属性用以指定时间函数,控制动画节奏,类似于运动的加速度,有以下几种类型。记住,这是一个数组,你有几个子路径就应该传入几个元素
            属性值描述:
                1 kCAMediaTimingFunctionLinear//线性
                2 kCAMediaTimingFunctionEaseIn//淡入
                3 kCAMediaTimingFunctionEaseOut//淡出
                4 kCAMediaTimingFunctionEaseInEaseOut//淡入淡出
                5 kCAMediaTimingFunctionDefault//默认

        calculationMode:该属性决定了物体在每个子路径下是跳着走还是匀速走,跟timeFunctions属性有点类似
            属性值描述:
                1 const kCAAnimationLinear//线性,默认
                2 const kCAAnimationDiscrete//离散,无中间过程,但keyTimes设置的时间依旧生效,物体跳跃地出现在各个关键帧上
                3 const kCAAnimationPaced//平均,keyTimes跟timeFunctions失效
                4 const kCAAnimationCubic//平均,同上
                5 const kCAAnimationCubicPaced//平均,同上
     */
    animation.delegate = self;

    switch (count) {
        case 1:
        {
            animation.keyPath = @"position";
            CGPoint centerP = self.view.center;
            CGFloat L = [UIScreen mainScreen].bounds.size.width - 100;
            NSValue *value1 = [NSValue valueWithCGPoint:centerP];
            NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(centerP.x - L/2, centerP.y - L/2)];
            NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(centerP.x + L/2, centerP.y - L/2)];
            NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(centerP.x + L/2, centerP.y + L/2)];
            NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(centerP.x - L/2, centerP.y + L/2)];
            NSValue *value6 = [NSValue valueWithCGPoint:CGPointMake(centerP.x - L/2, centerP.y - L/2)];
            NSValue *value7 = [NSValue valueWithCGPoint:centerP];
            animation.values = @[value1,value2,value3,value4,value5,value6,value7];

            //animation.keyTimes = @[@(0),@(0.1),@(0.3),@(0.5),@(0.7),@(0.9),@(1)];
            animation.duration = 5;

            animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        }
            break;
        case 2:
        {
            animation.keyPath = @"position";
            CGMutablePathRef path = CGPathCreateMutable();
            CGFloat main_screen_w = [UIScreen mainScreen].bounds.size.width;
            CGFloat main_screen_h = [UIScreen mainScreen].bounds.size.height;
            CGFloat view_w = 100;
            CGPathAddEllipseInRect(path, NULL, CGRectMake(view_w/2, view_w/2, main_screen_w - view_w, main_screen_h - view_w - 49));
            animation.path = path;
            CGPathRelease(path);

            animation.duration = 10;

            animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        }
            break;
        case 3:
        {
            animation.keyPath = @"transform.rotation.z";
            animation.values = @[@(0),@(M_PI_4),@(-M_PI_4),@(0)];
            animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
            animation.duration = 2;
            animation.repeatCount = MAXFLOAT;
        }
            break;

        default:
            break;
    }

    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;

    //3.添加动画到图层
    [view.layer addAnimation:animation forKey:nil];
}

3.CATransition:过度动画

- (IBAction)swipeGestureAction:(UISwipeGestureRecognizer *)sender {
    NSString *picName;
    CATransition *animation = [CATransition animation];
    /* 转场动画
         动画属性:
         type:执行什么样的动画。
         属性取值:
                fade     //交叉淡化过渡(不支持过渡方向) kCATransitionFade
                push     //新视图把旧视图推出去  kCATransitionPush
                moveIn   //新视图移到旧视图上面   kCATransitionMoveIn
                reveal   //将旧视图移开,显示下面的新视图  kCATransitionReveal
                cube     //立方体翻滚效果
                oglFlip  //上下左右翻转效果
                suckEffect   //收缩效果,如一块布被抽走(不支持过渡方向)
         rippleEffect //滴水效果(不支持过渡方向)
         pageCurl     //向上翻页效果
                pageUnCurl   //向下翻页效果
                cameraIrisHollowOpen  //相机镜头打开效果(不支持过渡方向)
                cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向)
         startProgress:动画从什么时候开始(相对于整个动画过程)
         endProgress:动画从什么时候结束(相对于整个动画过程)

         subType:动画的方向
          kCATransitionFromRight:从右边
          kCATransitionFromLeft:从左边
          kCATransitionFromBottom:从底部
          kCATransitionFromTop:从上边
     */
    if (sender.direction == UISwipeGestureRecognizerDirectionRight) {
        self.pageNumber --;
        if (self.pageNumber < 0) {
            self.pageNumber = 8;
        }
        picName = [NSString stringWithFormat:@"%i.jpg",abs(self.pageNumber + 1)];
        animation.type = @"pageUnCurl";
        //animation.subtype = kCATransitionFromRight;
        animation.duration = 0.5;
    }
    else if (sender.direction == UISwipeGestureRecognizerDirectionLeft)
    {
        self.pageNumber ++;
        if (self.pageNumber > 8) {
            self.pageNumber = 0;
        }
        picName = [NSString stringWithFormat:@"%i.jpg",self.pageNumber + 1];
        animation.type = @"pageCurl";
        animation.subtype = kCATransitionFromBottom;
        animation.duration = 0.5;
    }
    self.imageView.image = [UIImage imageNamed:picName];
    [self.imageView.layer addAnimation:animation forKey:nil];
}

4.CAAnimationGroup:组动画

- (void)groupAnimation
{
    //1.创建组动画
    CAAnimationGroup *group = [CAAnimationGroup animation];
    //2.将其他动画加入组动画中
    group.animations = @[[self creatOpacityAnimation],[self creatKeyfromAnimation]];
    group.duration = 0.5;
    group.removedOnCompletion = NO;
    group.fillMode = kCAFillModeForwards;
    //1.将动画组添加到图层上
    [self.button.layer addAnimation:group forKey:nil];
}
- (CABasicAnimation *)creatOpacityAnimation
{
    CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"opacity";
    animation.fromValue = @(0);
    animation.toValue = @(1);

    return animation;
}
- (CAKeyframeAnimation *)creatKeyfromAnimation
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    animation.keyPath = @"position";
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddArc(path, NULL, self.view.center.x + 50, self.view.center.y, 50, M_PI, 0, YES);
    animation.path = path;

    return animation;
}

5.View动画

            //核心动画都是假象,并没有改变真实的属性。
            [UIView transitionWithView:self.view duration:0.5 options:UIViewAnimationOptionTransitionCurlUp animations:^{
                self.index ++;
                if (self.index > 8) {
                    self.index = 0;
                }
                self.imageVIew.image = [UIImage imageNamed:[NSString stringWithFormat:@"%i.jpg",(int)self.index + 1]];
            } completion:nil];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值