iOS Core Animation 核心动画
2016-04-15 18:29
531 查看
Core Animation
图中紫色虚线表示继承关系,红色虚线表示遵守协议,核心动画中所有类都遵守CAMediaTiming协议;
CAAnimation包括的子类:
1.CABasicAnimation:基本动画,通过设定起始点,终点,时间,动画会沿着你设定的点进行移动。2.CAKeyframeAnimation:帧动画,通过设定起始点,中间关键点,终点,时间,动画会沿着你设定的轨迹进行移动。
3.CAAnimationGroup:组合动画,把layer所有动画都组合起来,可以同时执行。
4.CATransition:转场动画,页面之间跳转时使用。
CAAnimation
是所有动画类的父类,负责设置动画的时间和速度,是个抽象类,不能直接使用。基本属性:
duration:动画持续的时间,默认是0;
repeatCount:动画执行的次数,无线循环可以写HUGE_VALF或者MAXFLOAT,默认是0;
repeatDuration:动画重复的时间,默认是0;
beginTime:动画延迟执行时间,如果想要延迟2秒,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()是图层当前的时间,默认是0;
autoreverses:动画是否返回,默认是NO不返回;
speed:动画执行的速度,默认是1,如果设置为2,动画执行的时间duration减半;
timeOffset:设置一个时间偏移量,根据父类的动画时间来确定时间;
removedOnCompletion:默认为YES,动画执行完毕后会从图层中移除,图形会恢复到动画执行前的状态。如果想让图形保持显示在动画执行后的状态,那就设置为NO,不过还要设置fillMode为KCAFillModeForwards;
fillMode:动画开始前和动画结束后的行为;
timingFunction:速度控制函数,控制动画运动的节奏;
delegate:动画代理;
fillMode属性:
想要fillMode有效,最好设置removedOnCompletion为NO;
kCAFillModeRemoved:这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态;
kCAFillModeForwards:当动画结束后,layer会一直保持着动画最后的状态;
kCAFillModeBackwards:在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始;
kCAFillModeBoth:这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态;
CAMediaTimingFunction速度控制函数:
kCAMediaTimingFunctionLinear:线性,匀速,一个相对静态的感觉;
kCAMediaTimingFunctionEaseIn:渐进,动画缓慢进入,然后加速离开;
kCAMediaTimingFunctionEaseOut:渐出,动画全速进入,然后缓慢到达目的地;
kCAMediaTimingFunctionEaseInEaseOut:渐进渐出,动画缓慢的进入,中间加速,然后减速的到达目的地;
kCAMediaTimingFunctionDefault:默认状态;
CAPropertyAnimation
是CAAnimation的子类,也是个抽象类,要想创建动画,应使用它的子类CABasicAnimation和CAKeyframeAnimation。基本属性:
keyPath:设置动画的类型,想要实现什么样的动画效果。
transform.scale.x:x轴方向伸缩;
transform.scale.y:y轴方向伸缩;
transform.scale.z:z轴方向伸缩;
transform.scale:x,y,z轴方向都伸缩;
transform.rotation.x:沿x轴方向旋转;
transform.rotation.y:沿y轴方向旋转;
transform.rotation.z:沿z轴方向旋转;
transform.rotation:沿z轴方向旋转;
position.x:沿x轴方向移动;
position.y:沿y轴方向移动;
position.z:沿z轴方向移动;
position:按x,y坐标点移动;
CABasicAnimation 基本动画
基本属性:fromValue:动画的起始值;
toValue:动画的结束值;
byValue:在当前位置增加多少数值;
三个属性至少有两个不能为空。当byValue为空时,动画从fromValue到toValue执行运动;当toValue为空时,动画从fromValue到fromValue+byValue执行运动;当fromValue为空时,动画从toValue-byValue到toValue执行运动。
例子:模仿心动的动画
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 50, 50)]; [button setImage:[UIImage imageNamed:@"heart"] forState:UIControlStateNormal]; [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside]; button.adjustsImageWhenHighlighted = NO; [self.view addSubview:button]; } -(void)buttonAction:(UIButton *)button { CALayer *scaleLayer = [[CALayer alloc] init]; //layer层添加图片 scaleLayer.contents = (id)[UIImage imageNamed:@"heart"].CGImage; scaleLayer.frame = CGRectMake(0, 0, 50, 50); [button.layer addSublayer:scaleLayer]; CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0]; scaleAnimation.toValue = [NSNumber numberWithFloat:1.5]; scaleAnimation.autoreverses = YES; scaleAnimation.fillMode = kCAFillModeForwards; scaleAnimation.repeatCount = 2; scaleAnimation.duration = 0.8; [scaleLayer addAnimation:scaleAnimation forKey:@"scaleAnimation"]; }
CAKeyframeAnimation 关键帧动画
基本属性:values:存放关键帧(keyframe),在动画执行期间,会逐个经过这些关键帧;
path:动画的路径,CGPathRef或CGMutablePathRef类型,让层跟着路径移动。设置了path,values就不起作用了。path只对CALayer中的position移动起作用;
keyTimes:可以为对应的关键帧取对应的时间点,其取值范围是0到1;keyTimes每一个时间值都对应values中的每一帧;当keyTimes没有设置的时候,各个关键帧直接的时间是平分的;
timingFunctions:存放速度函数,控制动画运动的速度,类型如上;
calculationMode:该属性决定图形在每个子路径下是跳着走还是匀速走,与timingFunctions属性类似;
calculationMode属性:
kCAAnimationLinear:默认值,当关键帧为坐标点的时候,关键帧之间直接直线相连进行差值计算,线性;
kCAAnimationDiscrete:离散,没有中间过程,直接在每个关键帧上逐个显示,keyTimes属性依旧生效,图形跳跃的出现在每一个关键帧上;
kCAAnimationPaced:使动画匀速进行,设置的keyTimes和timingFunctions无效;
kCAAnimationCubic:针对关键帧为坐标点时,对关键帧进行圆滑曲线相连,目的是使图形的运行轨迹变得圆滑;
kCAAnimationCubicPaced:使图形的运行变得圆滑且匀速,设置的keyTimes和timingFunctions无效;
例子:心沿着轨迹运动
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { CGFloat x = (375-50)/2; CGFloat y = (667-80); CALayer *animationLayer = [[CALayer alloc] init]; animationLayer.contents = (id)[UIImage imageNamed:@"heart"].CGImage; animationLayer.frame = CGRectMake(x, y, 50, 50); [self.view.layer addSublayer:animationLayer]; CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; keyframeAnimation.values = @[[NSValue valueWithCGPoint:CGPointMake(x, y)],[NSValue valueWithCGPoint:CGPointMake(x-25, y-50)],[NSValue valueWithCGPoint:CGPointMake(x+25, y-50-50)],[NSValue valueWithCGPoint:CGPointMake(x-25, y-50-50-50)],[NSValue valueWithCGPoint:CGPointMake(x+25, y-50-50-50-50)]]; keyframeAnimation.duration = 3; keyframeAnimation.fillMode = kCAFillModeBoth; keyframeAnimation.removedOnCompletion = NO; keyframeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; keyframeAnimation.repeatCount = 1; [animationLayer addAnimation:keyframeAnimation forKey:@"keyframeAnimation"]; }
CAAnimationGroup 动画组
动画组,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间。基本属性:
animations:数组,保存一组动画对象;
例子:缩放、平移、旋转组合起来的动画
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. CALayer *groupLayer = [[CALayer alloc] init]; groupLayer.frame = CGRectMake(100, 100, 50, 50); groupLayer.cornerRadius = 10; groupLayer.backgroundColor = [UIColor orangeColor].CGColor; [self.view.layer addSublayer:groupLayer]; CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0]; scaleAnimation.toValue = [NSNumber numberWithFloat:1.5]; scaleAnimation.autoreverses = YES; scaleAnimation.repeatCount = MAXFLOAT; scaleAnimation.duration = 2; CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; moveAnimation.fromValue = [NSValue valueWithCGPoint:groupLayer.position]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(320-80, groupLayer.position.y)]; moveAnimation.autoreverses = YES; moveAnimation.repeatCount = MAXFLOAT; moveAnimation.duration = 2; CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; rotateAnimation.fromValue = [NSNumber numberWithFloat:0.0]; rotateAnimation.toValue = [NSNumber numberWithFloat:6.0*M_PI]; rotateAnimation.autoreverses = YES; rotateAnimation.repeatCount = MAXFLOAT; rotateAnimation.duration = 2; CAAnimationGroup *groupAnimation = [CAAnimationGroup animation]; groupAnimation.animations = @[scaleAnimation,moveAnimation,rotateAnimation]; groupAnimation.autoreverses = YES; groupAnimation.repeatCount = MAXFLOAT; groupAnimation.duration = 2; [groupLayer addAnimation:groupAnimation forKey:@"groupAnimations"]; }
CATransition 转场动画
CAAnimation的子类,用于做转场动画,能够为层提供移除屏幕和移入屏幕的动画效果。基本属性:
type:过渡动画的类型,默认是fade;
subtype:过渡动画的方向;
startProgress:动画起点,在整体动画的百分比;
endProgress:动画终点,在整体动画的百分比;
/* 过渡效果 fade //交叉淡化过渡(不支持过渡方向) kCATransitionFade push //新视图把旧视图推出去 kCATransitionPush moveIn //新视图移到旧视图上面 kCATransitionMoveIn reveal //将旧视图移开,显示下面的新视图 kCATransitionReveal cube //立方体翻滚效果 oglFlip //上下左右翻转效果 suckEffect //收缩效果,如一块布被抽走(不支持过渡方向) rippleEffect //滴水效果(不支持过渡方向) pageCurl //向上翻页效果 pageUnCurl //向下翻页效果 cameraIrisHollowOpen //相机镜头打开效果(不支持过渡方向) cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向) */ /* 过渡方向 kCATransitionFromRight kCATransitionFromLeft kCATransitionFromBottom kCATransitionFromTop */ // CATransition的使用 CATransition *anim = [CATransition animation]; anim.type = @"cube"; // 动画过渡类型 anim.subtype = kCATransitionFromTop; // 动画过渡方向 anim.duration = 1; // 动画持续1s // 代理,动画执行完毕后会调用delegate的animationDidStop:finished: anim.delegate = self;
相关文章推荐
- iOS 疑难杂症 — — 在 Storyboard 里 Add Size Class Customization 后再从代码里无法修改的问题
- iOS之QQ粘性布局
- IOS atomic与nonatomic,assign,copy与retain的定义和区别
- IOS多线程
- iOS学习笔记28-系统服务(一)短信和邮件
- iOS学习笔记28-系统服务(一)短信和邮件
- iOS 学习资料整理
- IOS转换和解析JSON数据
- iOS使用自定义字体
- IOS小技巧-Xcode里面设置每个类名的前缀
- iOS后台定位实现
- iOS label设置内容为HTML
- iOS获取当前无线连接的SSID信息和WI-FI名称
- ios 多线程简介
- IOS小技巧-xcode代码块
- iOS深入学习(再谈block)
- iOS 现有的运营商手机号正则表达式
- iOS开发之语音功能实现
- IOS简单的离线缓存实现
- IOS懒加载