300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > iOS 核心动画 Core Animation浅谈

iOS 核心动画 Core Animation浅谈

时间:2019-06-20 19:20:18

相关推荐

iOS 核心动画 Core Animation浅谈

代码地址如下:

/demo/11603.html

前记

关于实现一个iOS动画,如果简单的,我们可以直接调用UIView的代码块来实现,虽然使用UIView封装的方法很方便,但是这只能用于一些简答的动画,如果是一些复杂的动画呢?这就不得不去研究下核心动画Core Animation(包含在Quartz Core框架中)了。这这之前我们必须了解,CALayer就包含在Quartz Core框架中,这是一个跨平台的框架,既可以用在iOS中又可以用在Mac OS X中。在使用Core Animation开发动画的本质就是将CALayer中的内容转化为位图从而供硬件操作,所以要熟练掌握动画操作必须熟悉CALayer,关于CALayer就不在这里讲了。今天主要是分析核心动画,iOS 中的核心动画又分为下面几种:基础动画、关键帧动画、动画组、转场动画、弹簧动画。下面我们先来了解下各个动画之间的关系

动画简介
CAAnimation

@interface CAAnimation : NSObject<NSCoding, NSCopying, CAMediaTiming, CAAction>{@privatevoid *_attr;uint32_t _flags;}

这是核心动画的基类,不能直接使用,主要负责动画的时间、速度等,从上面可以看出是准守CAMediaTiming协议的。

CAPropertyAnimation

属性动画的基础类,继承自CAAnimation,不能直接使用。何谓属性动画呢?即通过修改属性值就可以产生动画效果。

CAAnimationGroup

动画组,继承自CAAnimation,顾名思义就是一种组合动画,可以通过动画组来进行所有动画行为的统一控制,组中所有动画效果可以并发执行。

CATransition

转场动画,继承自CAAnimation,主要是通过滤镜来进行动画的效果设置

CABasicAnimation

基础动画,继承自CAPropertyAnimation,通过属性控制动画的参数,只要初始状态和结束状态

CAKeyframeAnimation

关键帧动画,继承自CAPropertyAnimation,也是通过属性控制动画参数,但是与基础动画不同的是有多个控制状态,并且可以通过path来实现动画

CASpringAnimation

弹簧动画,是在iOS 9中引入的,继承自CABasicAnimation,用于制作弹簧动画

动画使用

在使用动画之前,先补充个知识点—UIBezierPath, 这在动画使用的过程中会经常用到

核心动画

要使用核心动画,我们必须先了解下其属性,这里我们先看其遵守的协议<CAMediaTiming>

CAAnimation属性

关于fillMode的四种情况:

kCAFillModeRemoved默认值,动画结束后,layer会恢复到之前的状态

kCAFillModeForwards当动画结束后,layer会一直保持着动画最后的状态,而removedOnCompletion的默认属性值是YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO

kCAFillModeBackwards在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。

kCAFillModeBoth这个其实就是上面两个的合成,动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态

关于速度CAMediaTimingFunction控制的四种情况

-kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉

kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开

kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地

kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。

属性动画

从上图中我们知道,属性动画是继承自核心动画,在其API中我们可以看到有如下函数和属性

+ (instancetype)animationWithKeyPath:(nullable NSString *)path;@property(nullable, copy) NSString *keyPath;

其中都有keyPath,这又是什么呢?这就是属性动画与动画组和转场动画不同之处。通过指定CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。比如,指定@"opacity"keyPath,就修改CALayeropacity属性的值,以达到透明度变化的动画效果

下面我们列举一些常用的animationWithKeyPath

基础动画

基础动画是继承自属性动画,所以在使用的时候,我们最主要的就是通过属性来控制动画,比如设置初始值、结束值,当然还有核心动画的其他属性。

- (void)showAnimation{CAShapeLayer * circle = [CAShapeLayer layer];circle.frame = self.view.bounds;//UIBezierPath * circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds)) radius:self.normalSize.width/2 -1 startAngle:0 endAngle:2*M_PI clockwise:YES];circle.path = circlePath.CGPath;circle.strokeColor = [UIColor blueColor].CGColor;circle.fillColor = nil;[self.view.layer addSublayer:circle];//通过圆的strokeStart 改变来进行改变CABasicAnimation * strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];strokeStartAnimation.fromValue = @(0.2);strokeStartAnimation.toValue = @(0);//通过圆的strokeEnd 改变来进行改变CABasicAnimation * strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];strokeEndAnimation.fromValue = @0.5;strokeEndAnimation.toValue = @(1.0);//通过圆的transform.rotation.z 改变来进行改变CABasicAnimation * rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];rotationAnimation.fromValue = @(0);rotationAnimation.toValue = @(-M_PI * 2);//组合动画CAAnimationGroup * group = [CAAnimationGroup animation];group.duration = 5;group.removedOnCompletion = NO;group.fillMode = kCAFillModeForwards;group.animations = @[strokeStartAnimation,strokeEndAnimation,rotationAnimation];[circle addAnimation:group forKey:nil];}

在上面的基础动画代码中,我只用了最基础的两个属性,fromValuetoValue,而其它属性呢?由于后面用到了动画组,所以讲其它属性在动画组进行了设置。[circle addAnimation:group forKey:nil];这句代码中,key我设置的为nil,如果不设置为nil的时候,是什么意思呢?这个其实就是我们的动画设置了一个key,可以用来区别是哪一个动画,在后面我会举例说明。

上面代码对应的效果如下:

关键帧动画

关键帧动画也是属性动画,与基础动画最主要不同的是在两个参数上,NSArray *valuesCGPathRef path,通过这个我们可以知晓,关键帧动画可以设置多个控制状态

如下:

//用value的方式进行展示动画- (void)showKeyFrameAnimationWithValues{CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];NSValue *key1 = [NSValue valueWithCGPoint:_beginPoint];NSValue *key2 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];NSValue *key3 = [NSValue valueWithCGPoint:CGPointMake(150, 50)];NSValue *key4 = [NSValue valueWithCGPoint:CGPointMake(300, 250)];animation.values = @[key1,key2,key3,key4];animation.duration = 5.0;animation.delegate = (id)self;// animation.autoreverses = true;//是否按路径返回// animation.repeatCount = HUGE;//是否重复执行animation.removedOnCompletion = NO;//执行后移除动画animation.fillMode = kCAFillModeForwards;//存储位置[animation setValue:key4 forKey:@"keyframeAnimationLocation"];[_fishImageView.layer addAnimation:animation forKey:@"keyframeAnimation_fish"];}

而且还可以设置路径,这也是其最大的特点

如下:

//用CGPathRef的方式进行展示动画- (void)showKeyFrameAnimationWithPath{CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];UIBezierPath *path = [UIBezierPath bezierPath];[path moveToPoint:_fishImageView.layer.position];//三次贝塞尔曲线[path addCurveToPoint:CGPointMake(300, 200) controlPoint1:CGPointMake(150, 400) controlPoint2:CGPointMake(230, -100)];animation.path = path.CGPath;animation.duration = 5.0;animation.delegate = (id)self;[_fishImageView.layer addAnimation:animation forKey:@"keyframeAnimation_path_fish"];}

效果如下,这里就暂时只给出values的效果

在上面的两个方法中,对layer设置了两个不同的key,分别为keyframeAnimation_fishkeyframeAnimation_path_fish

前面我提到过,通过这个可以判断是哪一种动画,这里我们在动画结束的地方进行区分一下

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{if ([anim isEqual:[_fishImageView.layer animationForKey:@"keyframeAnimation_fish"]]){// [CATransaction begin];// //禁用隐式动画// [CATransaction setDisableActions:YES];_fishImageView.layer.position = [[anim valueForKey:@"keyframeAnimationLocation"] CGPointValue];// //提交事务// [CATransaction commit];}else if ([anim isEqual:[_fishImageView.layer animationForKey:@"keyframeAnimation_path_fish"]]){}}

动画组

动画组其实很简单,就是将许多动画组合在一起

在上面的基础动画中,我也用到了动画组,下面再贴上一组动画组合效果

//发射- (void)launchAnimation{CABasicAnimation *animation1 = [CABasicAnimation animationWithKeyPath:@"transform.scale.y"];animation1.fromValue = @(1.0);animation1.toValue = @(1.5);CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];animation2.fromValue = @(1.0);animation2.toValue = @(1.5);CABasicAnimation *animation3 = [CABasicAnimation animationWithKeyPath:@"position"];animation3.fromValue = [NSValue valueWithCGPoint:_ballLayer.position];animation3.toValue = [NSValue valueWithCGPoint:CGPointMake(self.view.frame.size.width - (30 * 1.3)/2.0 , _ballLayer.position.y - 200)];CAAnimationGroup *anima = [CAAnimationGroup animation];anima.animations = @[animation1, animation2,animation3];anima.duration = 1.0;anima.delegate = (id)self;anima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];anima.fillMode = kCAFillModeForwards;anima.removedOnCompletion = NO;[_ballLayer addAnimation:anima forKey:@"group_launch"];}

在后面的demo里有完整的代码,这里只是截取了部分代码

效果如下:

转场动画

在了解转场动画之前,我们先了解其两个参数,通过这些参数,我们就能很清楚的了解其效果

-type转场类型

-subtype动画子类型

在了解上面两个属性后,对应转场动画,就差不多了

部分代码如下

- (void)transition:(BOOL)next{CATransition *transition = [CATransition animation];transition.type = @"cube";if (next){transition.subtype = kCATransitionFromLeft;}else{transition.subtype = kCATransitionFromRight;}transition.duration = 1.0;_imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld.jpg",(long)_currentIndex]];[_imageView.layer addAnimation:transition forKey:@"transitionAnimation"];}

效果如下

弹簧动画

弹簧动画是在iOS 9后才出现的,在这之前,我们可以通过下面的方法来实现

[UIView animateWithDuration:5.0 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveLinear animations:^{} completion:nil];

iOS 9后苹果公开了这一API,我们先对其中的属性进行分析,因为代码中有注释,所以就直接贴一部分代码

//质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大positionAnimation.mass = 0.1;//阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快positionAnimation.damping = 2;//刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快positionAnimation.stiffness = 50;//初始速率,动画视图的初始速度大小//速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反positionAnimation.initialVelocity = -10;

关于弹簧动画,我也写了一个例子,效果如下

项目文件截图:
写在最后

关于核心动画,差不多就简单的介绍这么点,如有什么不对的还望各位多多指教,不甚感激。iOS 核心动画 Core Animation浅谈

代码地址如下:

/demo/11603.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。