IOS动画总结

IOS动画

动画提供了界面不同状态间的连续虚拟变换,在iOS中动画可以用于重新配置视图,改变大小,改变层级,隐藏他们等等。

其中动画有两个级别的操作方式,UIKit Animation用于UIView对象,其封装了Core Animation,而Core Animation用于CALayer层对象,操作更加底层。

哪些对象可以用于动画?

UIKit Animation可以修改UIView属性有:

frame,即改变视图的大小和位于父视图的位置 
bounds,修改视图的大小 
center,修改位于父视图的位置 
transform,视图的缩放、旋转,只能在2D界面变化 
alpha,修改视图的透明度 
backgroundColor,修改视图的背景色 
contentStretch,修改视图的拉伸

Core Animation可以修改CALayer属性有:

layer的大小和位置 
layer的center点 
layer的3D变换 
layer的层级变换 
layer的阴影 
layer的边框 
layer的一部分的拉伸变换 
layer的不透明度 
layer剪切超出边界的部分 
layer的contents 
layer的光栅

UIKit Animation

使用基于Block的方法

animateWithDuration:animations:animateWithDuration:delay:options:animations:completion:

例子:


[UIView animateWithDuration:1.0 animations:^{
        firstView.alpha = 0.0;
        secondView.alpha = 1.0;
}];

animateWithDuration:animations:completion:

例子:


// Fade out the view right away
    [UIView animateWithDuration:1.0
        delay: 0.0
        options: UIViewAnimationOptionCurveEaseIn
        animations:^{
             thirdView.alpha = 0.0;
        }
        completion:^(BOOL finished){
            // Wait one second and then fade in the view
            [UIView animateWithDuration:1.0
                 delay: 1.0
                 options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                    thirdView.alpha = 1.0;
                 }
                 completion:nil];
        }];
使用基于Begin/Commit的方法

该方法用于ios3.2及之前版本,4.0及之后版本需要使用block方式。


[UIView beginAnimations:@"ToggleViews" context:nil];
    [UIView setAnimationDuration:1.0];

    // Make the animatable changes.
    firstView.alpha = 0.0;
    secondView.alpha = 1.0;

    // Commit the changes and perform the animation.
    [UIView commitAnimations];

Core Animation

Core Animation基础

动画层级图 

动画可操作修改的属性 Layer对象的坐标系统

layer使用了两套坐标系统, 
第一套为使用编程点定义的坐标系统,也是平时编程中使用最多的坐标 第二套为单元坐标系统,犹如以前数学学习时常将坐标换算到单位坐标系[0,1]进行计算 前者较后者用于精度要求高的场景。

Anchor Points的含义 锚点的含义是指,当我们对一个视图定义时,视图中的其它元素均相对于此点进行相对计算。 Layer Trees简介

Layer是通过tree的结构组织起来,共有三种Layer tree 
model layer tree presentation tree render tree

model Layer tree中的Layer是我们通常意义说的Layer。当我们修改layer中的属性时,就会立刻修改model layer tree。 
layer.position = CGPointMake(0,0); //这里的修改会直接影响model layer tree

presentation tree是Layer在屏幕中的真实位置。比如我们创建一个动画


[UIView animateWithDuration:5.0f 
                  animations:^{ 
                    self.animationLabel.center = CGPointMake(200, 400); 
                  }]; 

 //这里用一个Timer print presentLayer的位置。 
 CALayer *layer = self.animationLabel.layer.presentationLayer; 

 NSLog(@"model:%@, presentLayer%@", NSStringFromCGPoint(self.animationLabel.layer.position), NSStringFromCGPoint(layer.position)); 
 

下面是屏幕输出结果


model:{73.5, 155.5}, presentLayer{73.5, 155.5} 
model:{200, 400}, presentLayer{73.559769, 155.61552}//开始动画 
model:{200, 400}, presentLayer{73.814095, 156.10709} 
model:{200, 400}, presentLayer{74.267357, 156.98315} 
... 
... 
... 
model:{200, 400}, presentLayer{199.99576, 399.99182} 
model:{200, 400}, presentLayer{200, 400} 
 

render tree 在apple的render server进程中,是真正处理动画的地方。而且线程的优先级也比我们主线程优先级高。所以有时候即使我们的App主线程busy,依然不会影响到手机屏幕的绘制工作。(参考)

Core Animation使用

动画类的继承关系 CAAnimation

其中,CAAnimation是抽象基类,支持CAMediaTiming和 CAAction,其他动画类均继承自此类。 常见属性有:

duration,动画持续的时间;

repeatCount,动画重复的次数;

timingFunction,控制动画运行,包括kCAMediaTimingFunctionLinear,kCAMediaTimingFunctionEaseInkCAMediaTimingFunctionEaseOutkCAMediaTimingFunctionEaseInEaseOut(渐进渐出为默认值)

delegate 代理方法有


 - (void)animationDidStart:(CAAnimation *)theAnimation
 - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
 

CAPropertyAnimation

CAPropertyAnimation是CAAnimation的子类,但是不能直接使用,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation

CABasicAnimation

CABasicAnimation类的使用方式就是基本的关键帧动画。

所谓关键帧动画,就是将Layer的属性作为KeyPath来注册,指定动画的起始帧和结束帧,然后自动计算和实现中间的过渡动画的一种动画方式。

CABasicAnimation使用例子:


CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];  
animation.duration = 2.5; // 动画持续时间  
animation.repeatCount = 1; // 不重复  
animation.beginTime = CACurrentMediaTime() + 2; // 2秒后执行  
animation.autoreverses = YES; // 结束后执行逆动画  

// 动画先加速后减速  
animation.timingFunction =  
    [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; 

    / 设定动画起始帧和结束帧  
animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)]; // 起始点  
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(320, 480)]; // 终点 
 [myView.layer addAnimation:animation forKey:@"move-layer"]; 

 // 动画终了后不返回初始状态  
animation.removedOnCompletion = NO;  
animation.fillMode = kCAFillModeForwards;  
 

CAKeyframeAnimation

如果是简单的动画CABasicAnimation就能完成,CAKeyframeAnimation(关键帧动画)弥补了基本动画只能传入一对对应值的不足,关键帧动画支持传入一套数值或一个路径来完成动画。


//例子demoView左右摇摆
    self.demoView.layer.anchorPoint = CGPointMake(0.5, 0.0);  
    CAKeyframeAnimation *animaiton = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];  

    NSArray *rotationVelues = @[@(M_PI_4), @(-M_PI_4), @(M_PI_4)];  
    animaiton.values = rotationVelues;  
    animaiton.duration = 3.0f;  
    animaiton.repeatCount = 10000; 
    [self.demoView.layer addAnimation:animaiton forKey:nil];  
 

使用贝塞尔路径:


    UIBezierPath *path = [UIBezierPath bezierPath];  
    [path moveToPoint:self.demoView.center]; 
    [path addCurveToPoint:CGPointMake(270, 410) controlPoint1:CGPointMake(0, Screen_Height) controlPoint2:CGPointMake(Screen_Width, 0)];
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];  
    animation.path = path.CGPath;  
    animation.duration = 3.0f;  
    animation.removedOnCompletion = NO;  
    animation.fillMode = kCAFillModeForwards;  
    [self.demoView.layer addAnimation:animation forKey:nil];  
 

CAAnimationGroup

动画组将多个动画组合后使用,在其设定运行时间内执行多个动画,当某单个动画的时间超过动画组的时间时,按动画组设定的时间截取。


 /* 动画1(在X轴方向移动) */  
CABasicAnimation *animation1 =  
    [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];  

// 终点设定  
animation1.toValue = [NSNumber numberWithFloat:80];; // 終点  


/* 动画2(绕Z轴中心旋转) */  
CABasicAnimation *animation2 =  
    [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];  

// 设定旋转角度  
animation2.fromValue = [NSNumber numberWithFloat:0.0]; // 开始时的角度  
animation2.toValue = [NSNumber numberWithFloat:44 * M_PI]; // 结束时的角度  


/* 动画组 */  
CAAnimationGroup *group = [CAAnimationGroup animation];  

// 动画选项设定  
group.duration = 3.0;  
group.repeatCount = 1;  

// 添加动画  
group.animations = [NSArray arrayWithObjects:animation1, animation2, nil nil];  
[myView.layer addAnimation:group forKey:@"move-rotate-layer"];  
 

CATransition CATransition实现了过渡动画



/*
NSString *types[4] = {kCATransitionMoveIn, kCATransitionPush, kCATransitionReveal, kCATransitionFade};
NSString *subtypes[4] = {kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom};
//立方 吸走 翻转 水波 翻页 翻页回
NSString *moreTypes[]={@"cube",@"suckEffect",@"oglFlip",@"rippleEffect",@"pageCurl",@"pageUnCurl",@"cameraIrisHollowOpen",@"cameraIrisHollowClose"};
*/

CATransition *animation = [CATransition animation];
[animation setDuration:0.4];
[animation setType: @"fade"];

[animation setSubtype: kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];

[self.navigationController.view.layer addAnimation:animation forKey:nil];

[self.navigationController popViewControllerAnimated:NO];


http://www.nohackcc.com/2015/01/22/iosdong-hua-zong-shu/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值