您的位置:首页 > 移动开发 > IOS开发

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: