CALayer包含在QuartzCore框架中,具备跨平台性,在iOS中使用Core Animation开发动画的本质是 将CALayer内容转化为位图从而供硬件操做 。并发
属性 | 描述 |
---|---|
anchorPoint | 和中心position重合的点,称为锚点,范围在(0~1,0~1) |
position | 图层中心点位置,至关于UIView的center |
bounds | 图层大小 |
opacity | 透明度,至关于UIView的alpha |
//自定义图层 CALayer *layer = [[CALayer alloc] init]; layer.bounds = CGRectMake(0, 0, PHOTO_HEIGHT, PHOTO_HEIGHT); layer.position = CGPointMake(160, 200); layer.backgroundColor = [UIColor redColor].CGColor; layer.cornerRadius = PHOTO_HEIGHT/2; //注意仅仅设置圆角,对于图形而言能够正常显示,可是对于图层中绘制的图片没法正确显示,当绘制一张图片到图层上的时候会从新建立一个图层添加到当前图层 //若是想要正确显示则必须设置masksToBounds = YES,剪切子图层 layer.masksToBounds = YES; //设置边框 layer.borderColor = [UIColor whiteColor].CGColor; layer.borderWidth = 2; //设置图层代理 layer.delegate = self; //添加图层到根图层 [self.view.layer addSublayer:layer]; //调用图层setNeedDisplay,不然代理方法不会被调用 [layer setNeedsDisplay];
注意:阴影效果没法和masksToBounds同时使用,由于masksToBounds的目的就是剪切外边框,而阴影效果恰好在外边框框架
CAAnimation
:核心动画的基类,不能直接使用,负责动画运行时间、速度的控制,自己实现了CAMediaTiming协议。CAPropertyAnimation
:属性动画的基类(经过属性进行动画设置,注意是可动画属性),不能直接使用。CAAnimationGroup
:动画组,动画组是一种组合模式设计,能够经过动画组来进行全部动画行为的统一控制,组中全部动画效果能够并发执行。CATransition
:转场动画,主要经过滤镜进行动画效果设置。CABasicAnimation
:基础动画,经过属性修改进行动画参数控制,只有初始状态和结束状态。CAKeyframeAnimation
:关键帧动画,一样是经过属性进行动画参数控制,可是同基础动画不一样的是它能够有多个状态控制。①. 初始化动画并设置动画属性
②. 设置动画属性初始值(能够省略)、结束值以及其余动画属性
③. 给图层添加动画动画
#pragma mark 移动动画 -(void)translatonAnimation:(CGPoint)location{ //1.建立动画并指定动画属性 CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; //2.设置动画属性初始值和结束值 basicAnimation.fromValue = [NSValue valueWithCGPoint:CGPointZero]; basicAnimation.toValue = [NSValue valueWithCGPoint:location]; //设置其余动画属性 basicAnimation.delegate = self;//设置代理 basicAnimation.duration = 3.0;//动画时间3秒 //basicAnimation.repeatCount = HUGE_VALF;//设置重复次数,HUGE_VALF可看作无穷大 //basicAnimation.removedOnCompletion = NO;//运行一次是否移除动画 //3.添加动画到图层,注意key至关于给动画进行命名,之后得到该动画时可使用此名称获取 [_layer addAnimation:basicAnimation forKey:@"MYBasicAnimation_Translation"]; }
执行上面的移动动画,会出现一个现象,那就是 动画结束后图层回到原来位置 ,这是为何呢?设计
由于图层动画的本质是图层内部的内容转化为位图,通过硬件操做造成的动画效果,其实图层自己在动画过程当中没有发生任何变化。3d
#pragma mark - 动画代理方法 #pragma mark 动画开始 -(void)animationDidStart:(CAAnimation *)anim{ if( [anim isKindOfClass:[CABasicAnimation class]] ) { CABasicAnimation *baseAnima = (CABasicAnimation *)anim; //使用key-value的方式保持终点位置坐标 [baseAnima setValue:baseAnima.toValue forKey:@"MTBasicAnimationLocation"]; } } #pragma mark 动画结束 -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ if( flag ) { //取出终点位置坐标,进行设置 _layer.position = [[anim valueForKey:@"MTBasicAnimationLocation"] CGPointValue]; } }
但这样执行后又会出现另一个问题,那就是动画结束后它有一个先回到起点再移动到终点的短暂动画效果,这是什么缘由呢?代理
是隐式动画致使的,对于非根图层,设置图层的可动画属性会产生自动动画效果(例如
position
,实际上除了frame
,其余属性都是可动画属性),这种动画效果称为隐式动画code
CABasicAnimation
作动画干吗,直接设置图层position
不就能够实现了吗?答案是这种隐式动画咱们很差控制动画时间等动画属性,它是系统自动帮咱们实现的过渡动画效果。在这里咱们要消除这种问题的话,可使用事务CATransaction
暂时消除隐式动画,只须要修改动画结束的代理方法:orm
#pragma mark 动画结束 -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ if( flag ) { [CATransaction begin];//开启事务 [CATransaction setDisableActions:YES];//禁止隐式动画 _layer.position = [[anim valueForKey:@"MTBasicAnimationLocation"] CGPointValue]; [CATransaction commit];//提交事务 } }
关于事务CATransaction
和这节主题不太相关,就不细讲,有兴趣能够本身去苹果官方文档查看具体使用方式对象
#pragma mark 旋转动画 -(void)rotationAnimation{ //1.建立动画并指定动画属性 CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; //2.设置动画属性初始值、结束值 basicAnimation.fromValue = [NSNumber numberWithFloat:M_PI_2]; basicAnimation.toValue = [NSNumber numberWithFloat:M_PI_2*3]; //设置其余动画属性 basicAnimation.duration = 6.0; basicAnimation.autoreverses = true;//旋转后再旋转到原来的位置 //4.添加动画到图层,注意key至关于给动画进行命名,之后得到该动画时可使用此名称获取 [_layer addAnimation:basicAnimation forKey:@"MYBasicAnimation_Rotation"]; }
- 经过 设置不一样的属性值 进行关键帧控制
- 经过 绘制路径 进行关键帧控制
下面是实例:blog
#pragma mark 关键帧动画第一种方式 -(void)translationAnimation1{ //1.建立关键帧动画并设置动画属性 CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; //2.设置关键帧,这里有四个关键帧,对于关键帧动画初始值不能省略 NSValue *key1 = [NSValue valueWithCGPoint:_layer.position]; NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(80, 220)]; NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(45, 300)]; NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(55, 400)]; NSArray *values = @[key1,key2,key3,key4]; keyframeAnimation.values = values; //设置其余属性 keyframeAnimation.duration = 8.0; keyframeAnimation.beginTime = CACurrentMediaTime() + 2;//设置延迟2秒执行 //3.添加动画到图层,添加动画后就会执行动画 [_layer addAnimation:keyframeAnimation forKey:@"MYKeyframeAnimation_Position1"]; } #pragma mark 关键帧动画第二种方式 -(void)translationAnimation2{ //1.建立关键帧动画并设置动画属性 CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; //2.设置路径 //绘制贝塞尔曲线 CGPathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, _layer.position.x, _layer.position.y);//移动到起始点 CGPathAddCurveToPoint(path, NULL, 160, 280, -30, 300, 55, 400);//绘制二次贝塞尔曲线 keyframeAnimation.path = path;//设置path属性 CGPathRelease(path);//释放路径对象 //设置其余属性 keyframeAnimation.duration = 8.0; keyframeAnimation.beginTime = CACurrentMediaTime() + 2;//设置延迟2秒执行 //3.添加动画到图层,添加动画后就会执行动画 [_layer addAnimation:keyframeAnimation forKey:@"MYKeyframeAnimation_Position2"]; }
就是多个动画的组合,直接来代码:
#pragma mark 建立动画组 -(void)groupAnimation{ //1.建立动画组 CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; //2.设置组中的动画和其余属性 CABasicAnimation *basicAnimation = [self rotationAnimation];//基本动画 CAKeyframeAnimation *keyframeAnimation = [self translationAnimation];//关键帧动画 animationGroup.animations = @[basicAnimation,keyframeAnimation]; animationGroup.delegate = self; //设置动画时间,若是动画组中动画已经设置过动画属性,则再也不生效 animationGroup.duration = 10.0; animationGroup.beginTime = CACurrentMediaTime() + 5;//延迟五秒执行 //3.给图层添加动画 [_layer addAnimation:animationGroup forKey:nil]; }
①. 建立转场动画
②. 设置转场类型、子类型(可选)及其余属性
③. 设置转场后的新视图并添加动画到图层
#pragma mark 转场动画 -(void)transitionAnimation:(BOOL)isNext{ //1.建立转场动画对象 CATransition *transition = [[CATransition alloc] init]; //2.设置转场类型,注意对于苹果官方没公开的动画类型只能使用字符串,并无对应的常量定义 transition.type = @"cube"; //设置转场方向类型 if (isNext) { transition.subtype = kCATransitionFromRight; }else{ transition.subtype = kCATransitionFromLeft; } //设置动画时常 transition.duration = 1.0f; //3.设置转场后的新视图添加转场动画 _imageView.image = [self getImage:isNext]; [_imageView.layer addAnimation:transition forKey:@"KCTransitionAnimation"]; }