在iOS中, 图形动画可以分为一下几个层次: 如图所示
CAAnimation
一 简单介绍*
- Core Animation,即核心动画, 它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能.
- Core Animation是跨平台的,可以用在Mac OS X和iOS平台。
- Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。不阻塞主线程,可以理解为在执行动画的时候还能点击(按钮)。
Core Animation的使用步骤
1.使用它需要先添加QuartzCore.framework框架和引入主头文件QuartzCore/QuartzCore.h(iOS7不需要)
2. .初始化一个CAAnimation对象,并设置一些动画相关属性
3. 通过调用CALayer的addAnimation:forKey:方法增加CAAnimation对象到CALayer中,这样就能开始执行动画了
4. 通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画
CoreAnimation时所有动画的父类, 但是不能直接使用, 应该使用他的子类
其常见属性有:
* duration: 动画的持续时间
* repeatCount : 动画重复次数
* timingFunction: 控制动画的运行节奏
说明: (1) 能用的动画类只有4个子类: CABaseAnimation/ CAKeyframeAnimation/ CATransition/ CAAnimationGroup
其中CAPropertyAnimation时CAAnimation的子类, 但是不能直接调用, 要想创建动画, 应该使用给它的两个子类: CABaseAnimation 和 CAKeyframeAnimation
他有个NSString类型的keyPath属性, 你可以指定CALayer的某个属性名位keyPath, 并且对CALayer的这个属性值进行修改, 达到相应的动画效果. 比如指定"position"为keyPath, 就会修改CALayer的position属性的值, 以达到平移的动画效果.
使用实例
CAAnimation基类
所有动画对象的父类, 负责控制动画的持续时间, 和速度, 是个抽象类, 不能直接使用. 应该使用其子类.
CAAnimation的属性:
@Property (retain) id delegate
为CAAnimation设置代理 默认为nil
@property (getter = isRemoveOnCompletion) BOOL removedOnCompletion
设置动画完成后, 动画效果从设置的layer上移除. 默认为YES
@property (retain) CAMediaTimingFunction *timingFunction
设置动画的 “时机”效果. 就是动画自身的 “节奏”. 比如: 开始快, 结束时变慢; 等,在动画过程中的 “时机” 效果
- (id) animation
创建并返回一个CAAnimation实例
- (id) defaultValueForKey:(NSString *) key
根据属性key, 返回相应的属性值
- (BOOL) shouldArchiveValueForKey:(NSString *) key
返回指定的属性值是否可以归档. key: 制定的属性. YES: 指明该属性可以被归档. NO: 不能被归档
协议方法
- (void) animationDidStart: (CAAnimation *) theAnimation
动画开始时, 执行的方法 theAnimation: 正在执行的动画的CAAnimation实例
- (void) anmationDidStop:(CAAnimation *) theAnimation finished:( BOOL) flag
动画执行完,或者动画为执行被删除时, 执行该方法.
theAnimation: 完成或者被删除的动画实例
flag: 标志该动画是执行完成或者被删除: YES: 执行完成.; NO: 被删除
CAMediaTiming协议
@property CFTimeInterval beginTime
Specifies the begin time of the receiver in relation to its parent object, if applicable. (required)
可以用于实现同一分组动画的异步执行
@property CFTimeInterval timeOffset
Specifies an additional time offset in active local time. (required)
开始时间位置的偏移量
@property float repeatCount
Determines the number of times the animation will repeat. (required)
@property CFTimeInterval repeatDuration
Determines how many seconds the animation will repeat for. (required)
@property BOOL autoreverses
Determines if the receiver plays in the reverse upon completion. (required)
@property float speed
Specifies how time is mapped to receiver’s time space from the parent time space. (required)
其实也比较好理解,如果一个动画A :duration为1秒,speed为1;而另一个动画B:duration为2秒,speed为2。则两个动画的效果是相同的。不过前提是它们的super layer相同
@property CFTimeInterval duration
Specifies the basic duration of the animation, in seconds. (required)
@property(copy) NSString *fillMode
Determines if the receiver’s presentation is frozen or removed once its active duration has completed. (required)
CAPropertyAnimation 属性动画
通过 layer的属性值变化完成动画,CALayer属性中凡是有Animation标示的均可作为动画的目标值. CAAnimation 类, 是一个抽象类. 遵循CAMediaTiming协议(可以调整时间, 包括连续时间, 速度, 重复次数 ) 和 CAAction协议(可以通过响应动作的方式来显示动画)!
常用的CYLayer 属性如下:
shadowOffset: 阴影偏移距离
shadowColor: 阴影颜色
shadowOpacity: 阴影透明度
shadowRadius: 阴影模糊程度
connerRadius: 圆角
transfrom: 使CALayer产生3D空间内的 平移/缩放/旋转 等变化
borderWidth: 描边粗细
borderColor: 描边颜色
anchorPoint: 锚点
position: 位置信息
zPositon: 不同layer的层级顺序
CABasicAnimation 基础动画 (提供了对单一动画的实现)
基础动画实例通过设置一个开始值和结束值完成对某一目标属相值的动画 通过属性动画中的子类CABasicAnimation来设置图层动画, 可以修改图层的position, transform.scale, transform.rotation 等等 基础动画提供了一个初始化方法和三个属性值 fromValue byValue 和 toValue, 但是这三个属性只能是三选2
基础动画的实现过程如下:
//1> 实例化基础动画对象, 在初始化方法中设置动画目标属性
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
//设置动画目标的起始值
basicAnimation.fromValue = @0;
//设置动画目标的结束值
basicAnimation.toValue = @(M_PI * 10000);
//设置动画时长
basicAnimation.duration = 5;
//设置动画的重复次数
basicAnimation.repeatCount = 10;
//设置动画自动翻转
basicAnimation.autoreverses = YES;
//为图层添加动画
[self.animatableView.layer addAnimation:basicAnimation forKey:@"basic"];
CAKeyFrameAnimation 关键帧动画(可以自定义动画路线)
这个类可以实现,某一属性按照一串的数值进行动画,就好像制作动画的时候一帧一帧的制作一样。
CAKeyframeAnimation 的一些比较重要的属性
方法名/属性名
作用
+ (id)animationWithKeyPath:(NSString *)path;
系统提供的构造器方法
@property CGPathRef path;
通过制定一个自己定义的path来让某一个物体按照这个路径进行动画
@property(copy) NSArray *values;
一个数组,提供了一组关键帧的值, 当使用path的 时候 values的值自动被忽略。
@property(copy) NSArray *keyTimes;
一个数组,设置每一帧的时间,其成员必须是NSNumber。设置详情查看API。
@property(copy) NSString *rotationMode;
设定关键帧中间的值是如何计算
//创建关键帧动画对象
CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置动画时长
keyFrameAnimation.duration = 5;
//创建贝塞尔曲线, 来设定视图移动的路径
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:150 startAngle:-M_PI_2 endAngle:-M_PI_2 * 5 clockwise:NO];
// //设置动画轨迹
keyFrameAnimation.path = circlePath.CGPath;
//为图层添加关键帧动画
[self.animatableView.layer addAnimation:keyFrameAnimation forKey:@"keyframe"];
CATransition 过度动画(可以提供渐变效果: 推拉push效果, 消退fade效果, 揭开reveal效果)
有两个重要属性:type(设置过度动画的效果) 和subType(设置过度动画的方向)
过度动画类型:
官方API
kCATransitionFade
kCATransitionMoveIn
kCATransitionPush
kCATransitionReveal
私有API
suckEffect 三角
rippleEffect 水波抖动
pageCurl 上翻页
pageUnCurl 下翻页
oglFlip 上下翻转
cameraIrisHollowOpen 镜头快门开
cameraIrisHollowClose 镜头快门
实例://layer层的过度动画
CATransition *transition = [CATransition animation];
//设置动画时长
transition.duration = 1;
transition.repeatCount = 1000;
transition.type = @”cube”;
transition.subtype = kCATransitionFromLeft;
[self.view.layer addAnimation:transition forKey:nil];CAAnimationGroup 组动画 //可以添加多个动画到组动画, 让他们同时执行
只有一个属性 @property(copy) NSArray *animations
组动画对象通过调用-setAnimations 这个方法增加
实例
//创建一个组动画
CAAnimationGroup *group = [CAAnimationGroup animation];
//设置动画时长
group.duration = 5;
//设置动画重复次数
group.repeatCount = 100;
group.autoreverses = YES;
//添加动画
group.animations = @[keyFrameAnimation,basicAnimation,bas];
//为图层添加动画
//[self.animatableView.layer addAnimation:group forKey:@”group”];
UIView动画
一 使用UIView的类方法设置动画
1.简单说明
UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持
执行动画所需要的工作由UIView类自动完成,但仍要在希望执行动画时通知视图,为此需要将改变属性的代码放在[UIViewbeginAnimations:nil context:nil]和[UIView commitAnimations]之间
UIKit 支持通过修改UIView的如下属性来设置动画 :
frame: 视图框架
alpha: 视图透明度
center: 视图位置
hidden: 视图隐藏
bounds: 视图大小
视图层次顺序
backgroundColor:背景颜色
transform: 视图转换
常见方法解析:
(void)setAnimationDelegate:(id)delegate 设置动画代理对象,当动画开始或者结束时会发消息给代理对象
(void)setAnimationWillStartSelector:(SEL)selector 当动画即将开始时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector
(void)setAnimationDidStopSelector:(SEL)selector 当动画结束时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector
(void)setAnimationDuration:(NSTimeInterval)duration 动画的持续时间,秒为单位
(void)setAnimationDelay:(NSTimeInterval)delay 动画延迟delay秒后再开始
(void)setAnimationStartDate:(NSDate *)startDate 动画的开始时间,默认为now
(void)setAnimationCurve:(UIViewAnimationCurve)curve 动画的节奏控制
(void)setAnimationRepeatCount:(float)repeatCount 动画的重复次数
(void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses 如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
(void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache 设置视图view的过渡效果, transition指定过渡类型, cache设置YES代表使用视图缓存,性能较好
实例:
//设置UIView动画开始
[UIView beginAnimations:@”UIViewAnimation” context:nil];
//设置动画时长, 以秒为单位
[UIView setAnimationDuration:3];
//设置动画的延时, 以秒为单位
[UIView setAnimationDelay:2];
//设置动画的线性关系
// UIViewAnimationCurveEaseInOut, 缓入缓出
// UIViewAnimationCurveEaseIn, 缓入
// UIViewAnimationCurveEaseOut, 缓出
// UIViewAnimationCurveLinear 线性
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
//设置动画是否自动翻转
[UIView setAnimationRepeatAutoreverses:YES];
//设置动画的重复次数
[UIView setAnimationRepeatCount:10];
//设置当前动画的代理对象
[UIView setAnimationDelegate:self];
//设置当前动画结束的代理对象
[UIView setAnimationDidStopSelector:@selector(animationStop)];
//要让视图相关属性的改变写在 beginAnimation 和 commitAnimation 之间, 该视图的属性就以动画的形式改变
self.animatableView.alpha = 0.8;
self.animatableView.bounds = CGRectMake(0, 0, 100, 100);
self.animatableView.center = CGPointMake(CGRectGetWidth(self.view.bounds) / 2, 400);
//提交动画
[UIView commitAnimations];
二 UIView的block动画(对类方法动画的封装 iOS4 之后可用)
//第一种Block
//参数1:动画时长 参数2:Block: 设置要修改的View属性
/*
[UIView animateWithDuration:2 animations:^{
self.changeView.backgroundColor = [UIColor orangeColor];
}];
*/
//第二种Block
/*
//参数1:动画时长 参数2:执行动画的Block: 设置要修改的View属性 参数3:动画完成后执行的block: 动画完成时调用
[UIView animateWithDuration:2 animations:^{
self.changeView.backgroundColor = [UIColor orangeColor];
} completion:^(BOOL finished) {
//finished判断动画是否完成
if (finished) {
NSLog(@”finished”);
}
}];
*/
//第三种Block/可以设置动画时长,动画延时,动画的参数,动画block,完成block
/*
[UIView animateWithDuration:2 delay:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
// 设置要修改的View属性
self.changeView.backgroundColor = [UIColor orangeColor];
} completion:^(BOOL finished) {
//finished判断动画是否完成
if (finished) {
NSLog(@”finished”);
}
}];
*/
//第四种block: springWithDamping:弹动的阻尼, initialSpringVwlocity:弹动的初始速率
/*
[UIView animateWithDuration:5 delay:0.3 usingSpringWithDamping:0.1 initialSpringVelocity:0.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.animatableView.frame = CGRectMake(self.animatableView.frame.origin.x, 300, 100, 100);
self.animatableView.frame = CGRectInset(self.animatableView.frame, -100, -100);
}
completion:^(BOOL finished) {
//finished判断动画是否完成
if (finished) {
NSLog(@"finished");
}
}
];
*/
三 UIView 的过渡动画
//对过度动画的封装
//第一种 单个动画的过度
//参数1: 改变的View 参数2:动画时长 参数3:动画类型 参数4 Block: 设置要修改的View属性 参数5:完成后的操作
[UIView transitionWithView:self.changeView duration:2 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
self.changeView.backgroundColor = [UIColor orangeColor];
} completion:^(BOOL finished) {
//finished判断动画是否完成
if (finished) {
NSLog(@"finished");
}
}];
//第二种 两个视图见的切换过度
//参数1: 当前View 参数2 : 将要过度到的View 参数3:动画时长 参数4:动画类型 参数5 Block: 设置要修改的View属性 参数6:完成后的操作
/*
[UIView transitionFromView:self.view toView:toView duration:3 options:UIViewAnimationOptionTransitionCrossDissolve completion:^(BOOL finished) {
if (finished) {
[UIView transitionFromView:toView toView:self.view duration:3 options:UIViewAnimationOptionTransitionCrossDissolve
completion:^(BOOL finished) {
//finished判断动画是否完成
if (finished) {
NSLog(@”finished”);
}
}
]; }];
*/