前言
做个知识汇总,日常动画的动画实现,看这篇应该足够了
iOS图形分层
越顶层,动画的封装程度越高,动画api就越简洁,本文章主要讲动画在UIKit层和CoreAnimation层的实现
UIKit层
UIViewAnimation
动画的实现过程:
[UIView beginAnimations:@"newAnimation" context:nil];
//设置动画的持续时间
[UIView setAnimationDuration:1.0];
//如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
[UIView setAnimationRepeatAutoreverses:YES];
//设置动画的运动曲线(线性、先快后慢、先慢后快)
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//动画的重复次数
[UIView setAnimationRepeatCount:10];
//动画动作定义
CGRect tmp = self.myView.frame;
tmp.origin.x += 100;
self.myView.frame = tmp;
//提交动画
[UIView commitAnimations];
UIViewAnimationWithBlocks
动画的实现过程:
//动画持续时间、延迟时间、动画执行函数
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
//动画动作定义
CGRect tmp = self.myView.frame;
tmp.origin.x = 300;
self.myView.frame = tmp;
} completion:nil];
Core Animation
Core Animation是直接作用在CALayer上的(并非UIView上)非常强大的跨Mac OS X和iOS平台的动画处理API,Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
CAAnimation可分为四种:
1.CABasicAnimation
通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
2.CAKeyframeAnimation
Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动
3.CAAnimationGroup
Group也就是组合的意思,就是把对这个Layer的所有动画都组合起来。PS:一个layer设定了很多动画,他们都会同时执行,如何按顺序执行我到时候再讲。
4.CATransition
这个就是苹果帮开发者封装好的一些动画
停止动画
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
// 让CALayer的时间停止走动
layer.speed = 0.0;
// 让CALayer的时间停留在pausedTime这个时刻
layer.timeOffset = pausedTime;
恢复动画
CFTimeInterval pausedTime = layer.timeOffset;
// 1. 让CALayer的时间继续行走
layer.speed = 1.0;
// 2. 取消上次记录的停留时刻
layer.timeOffset = 0.0;
// 3. 取消上次设置的时间
layer.beginTime = 0.0;
// 4. 计算暂停的时间(这里也可以用CACurrentMediaTime()-pausedTime)
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
// 5. 设置相对于父坐标系的开始时间(往后退timeSincePause)
layer.beginTime = timeSincePause;
CABasicAnimation的实现
基础动画,是CAPropertyAnimation子类
keyPath附录表:
CALayer* scaleLayer = [[CALayer alloc]init];
scaleLayer.backgroundColor = [UIColor blueColor].CGColor;
scaleLayer.frame = CGRectMake(60, 20, 50, 50);
scaleLayer.cornerRadius = 10;
[self.view.layer addSublayer:scaleLayer];
//动画类型
CABasicAnimation* scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
//动画的起始状态
scaleAnimation.fromValue = @1.0;
//动画的结束状态
scaleAnimation.toValue = @1.5;
//如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
scaleAnimation.autoreverses = YES;
/**
* fillMode决定当前对象在非active时间段的行为。(要想fillMode有效,最好设置removedOnCompletion = NO)
**/
scaleAnimation.fillMode = kCAFillModeForwards;
//动画重复次数
scaleAnimation.repeatCount = MAXFLOAT;
//动画持续时间
scaleAnimation.duration = 0.8;
//将动画添加到layer上面
[scaleLayer addAnimation:scaleAnimation forKey:@"scaleAnimation"];
CAKeyframeAnimation的实现
关键帧动画,也是CAPropertyAnimation的子类
与CABasicAnimation的区别是:
CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值
CALayer* blackPoint = [[CALayer alloc]init];
blackPoint.frame = CGRectMake(20, 80, 20, 20);
blackPoint.backgroundColor = [UIColor blackColor].CGColor;
blackPoint.cornerRadius = 10;
[self.view.layer addSublayer:blackPoint];
CGFloat originY = blackPoint.frame.origin.y;
CAKeyframeAnimation* keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//记录每一个关键帧
keyAnimation.values = @[[NSValue valueWithCGPoint:blackPoint.frame.origin],[NSValue valueWithCGPoint:CGPointMake(220, originY)],[NSValue valueWithCGPoint:blackPoint.frame.origin]];
//可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的
keyAnimation.keyTimes = @[[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.5],
[NSNumber numberWithFloat:1]];
//指定时间函数
keyAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
keyAnimation.repeatCount = 1000;
keyAnimation.autoreverses = YES;
keyAnimation.calculationMode = kCAAnimationLinear;
keyAnimation.duration = 4;
[blackPoint addAnimation:keyAnimation forKey:@"rectRunAnimation"];
CAAnimationGroup的实现
组动画,是CAAnimation的子类
可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行,可以通过设置动画对象的beginTime属性来更改动画的开始时间
CAAnimationGroup* group = [CAAnimationGroup animation];
//用来保存一组动画对象
group.animations = @[scaleAnimation];
group.duration = 0.8;
group.repeatCount = 3;
group.autoreverses = YES;
[scaleLayer addAnimation:group forKey:nil];
CATransition的实现
转场动画,是CAAnimation的子类,,能够为层提供移出屏幕和移入屏幕的动画效果。
UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果
有以下效果可以使用:
cube 方块
suckEffect 三角
rippleEffect 水波抖动
pageCurl 上翻页
pageUnCurl 下翻页
oglFlip 上下翻转
cameraIrisHollowOpen 镜头快门开
cameraIrisHollowClose 镜头快门开
CATransition* animation = [CATransition animation];
animation.duration = 1.0f;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
//执行完是否移除
animation.removedOnCompletion = NO;
//过渡效果
animation.type = @"cube";
//过渡方向
animation.subtype = kCATransitionFromRight;
//设置之后endProgress才有效
animation.fillMode = kCAFillModeForwards;
animation.endProgress = 1;
[imageView.layer addAnimation:animation forKey:nil];
欢迎订阅我的小专栏