iOS 动画笔记 (一)

你也肯定喜欢炫酷的动画!

在APP中,动画就是一个点睛之笔!可以给用户增加一些独特的体验感,估计也有许多的和我一样的,看着那些觉得不错的动画,也就只能流口水的孩子,毕竟可能不知道从哪里下手去写!动画学习的过程我会总结一个系列的出来,总结一下iOS中动画的一个学习的过程,以及当中出现的一些问题也会和大家分享。现总结几点在学习动画之前的知道的一些点,这些能帮助我们写好学好动画。

一:从这里 Quartz2D 开始

在我的学习过程中,我是先从 Quartz2D 开始学习的,它里面的贝塞尔曲线在我们创造精美的动画的过程中是必不可少的,Quartz 2D 它首先就是一个二维绘图引擎,同时支持iOS和Mac系统。下面这里一篇不错的文章,仔细的讲解了 Quartz 2D。想制作精美的动画,你就得懂Quartz 2D里面的贝塞尔曲线!你要仔细的学习了上面链接里面的内容,我想你也就掌握了 Quartz2D 了。

二: 接下来看看 CADisplayLink

就是这个 CADisplayLink,简单地说它就是一个定时器!定时器大家最熟悉的可能就是 NSTime了吧,那 CADisplayLink 和 NStime 又有什么区别呢?带着这些疑问往下看。

 CADisplayLink 是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。我们在应用中创建一个新的 CADisplayLink 对象,把它添加到一个runloop中,并给它提供一个 target 和 selector,它在屏幕刷新的时候调用, 一但 CADisplayLink 以特定的模式注册到runloop之后,每当屏幕需要刷新的时候,runloop就会调用CADisplayLink绑定的target上的selector,这时target可以读到 CADisplayLink 的每次调用的时间戳,用来准备下一帧显示需要的数据。例如一个视频应用使用时间戳来计算下一帧要显示的视频数据。在UI做动画的过程中,需要通过时间戳来计算UI对象在动画的下一帧要更新的大小等等。 NStime 的精确度就显得低了点,

 它们还是有很大的区别的,这是我们的伙伴总结的 定时器,写的很详细了,可以进去看看他们俩的区别。它们俩的创建看下面

// 创建 NSTimer 定时器
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(test) userInfo:nil repeats:YES];
// 停止定时器
[timer invalidate];
 
 
// 创建CADisplayLink 定时器
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(test:)];
// 将创建的displaylink添加到runloop中,否则定时器不会执行
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
// 停止定时器
[displayLink invalidate];
displayLink = nil;

三:先说说系统的吧!

(1) CALayer 实际上UIView是对CALayer封装,在CALayer的基础上再添加交互功能。UIView的显示必须依赖于CALayer。我们同样可以跟新建view一样新建一个layer,然后添加到某个已有的layer上,同样可以对layer调整大小、位置、透明度等。 具体讲CAlayer的属性

    (2) UIBezierPath   (贝塞尔曲线)

    (3) CAAnimation  (重点)

      首先 CAAnimation 可以分为以下几类:

  •    CABasicAnimation   基础动画,通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
  •   CAKeyframeAnimation   关键帧动画,可定制度比CABasicAnimation高,也是本系列的接下来的内容
  •   CAAnimationGroup   组动画,支持多个CABasicAnimation或者CAKeyframeAnimation动画同时执行

下面链接的文章能帮助大家很好的学习 CAAnimation!感谢作者!大家好好看看!

iOS动画(一)

iOS动画(二)

学完看看这个,经典的淘宝购物车效果:立即抢购图标会大致按照下面的贝塞尔曲线运动到购物车,完后消失,给大家附上大概的思路代码!代码写其实挺简单的,你完全可以试试!

-(void)buttonclick
{
     
    // http://www.jianshu.com/p/69caa3b68b43/comments/1352880  CAlay 详解
    layer = [[CALayer alloc]init];
    layer.frame = imageV.frame;
    // 包含的内容
    layer.contents = (__bridge id _Nullable)(imageV.image.CGImage);
    // 透明度
    layer.opacity = 1;
    [self.view.layer addSublayer:layer];
     
    // 起点和终点
    CGPoint starpoint = imageV.center;
    CGPoint stoppoint =  CGPointMake(self.view.bounds.size.width - 50, 300);
     
    // 贝塞尔曲线
    // http://www.jianshu.com/p/734b34e82135  贝塞尔曲线详解
    UIBezierPath * path = [UIBezierPath bezierPath];
    // 曲线的开始位置
    [path moveToPoint:starpoint];
    // 控制点
    CGPoint coltrolpoint = CGPointMake(starpoint.x + (stoppoint.x - starpoint.x)/3, 0);
    // 添加二维曲线
    [path  addQuadCurveToPoint:stoppoint controlPoint:coltrolpoint];
     
     
    CAKeyframeAnimation * animation =  [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.path = path.CGPath; // CGPath CGPathRef类型
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    animation.delegate=self;
    animation.duration = 0.8;
    animation.autoreverses = NO;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [layer addAnimation:animation forKey:@"buy"];
     
}
-(void)animationDidStop:(CAKeyframeAnimation *)anim finished:(BOOL)flag
{
    [layer removeFromSuperlayer];
}

四:能擦出火花

  你要了解了上面说的贝塞尔曲线和CADisplayLink,它俩碰撞其实已经能擦出火花了!你要真的认真的学习我上面不管是我写的还是给大家链接里面我们的同行写的博客,我相信基本的动画大家其实已经也差不多够用了,关在在于你怎么样去灵活的用它。

          最后在给大家一篇博客, CADisplayLink结合UIBezierPath的神奇妙用 就算是对上面只是的一个总结,这里面的动画都是有git源码的,你可以下载下来好好去研究研究!

          我会在这个系列的下一篇给大家介绍常用的动画三方库FaceBook出品的 pop 和 Canvas !      

 2017-06-20  更新:

 最近又翻出来在看转场动画的内容,感觉这篇真的值提到了一些动画的皮毛,很浅,下面是自己补充的知识点:

         认真总结一下核心的CoreAnimation:

         在理解CoreAnimation之前,必须也要理解UIView和CAlayer:

总接来说就是如下几点: 

  • 每个 UIView 内部都有一个 CALayer 在背后提供内容的绘制和显示,并且 UIView 的尺寸样式都由内部的 Layer 所提供。两者都有树状层级结构,layer 内部有 SubLayers,View 内部有 SubViews.但是 Layer 比 View 多了个AnchorPoint
  • 在 View显示的时候,UIView 做为 Layer 的 CALayerDelegate,View 的显示内容由内部的 CALayer 的 display
  • CALayer 是默认修改属性支持隐式动画的,在给 UIView 的 Layer 做动画的时候,View 作为 Layer 的代理,Layer 通过 actionForLayer:forKey:向 View请求相应的 action(动画行为)
  • layer 内部维护着三分 layer tree,分别是 presentLayer Tree(动画树),modeLayer Tree(模型树), Render Tree (渲染树),在做 iOS动画的时候,我们修改动画的属性,在动画的其实是 Layer 的 presentLayer的属性值,而最终展示在界面上的其实是提供 View的modelLayer
  • 两者最明显的区别是 View可以接受并处理事件,而 Layer 不可以

      再看看这个同行总结的CoreAnimation的结构树状图,这个对理解它还是很重要很有用的:

 说明:

        一:

        核心动画中所有类都遵守CAMediaTiming协议。                  CAAnaimation是个抽象类,不具备动画效果,必须用它的子类才有动画效果。

          二:

                 CAAnimationGroup和CATransition才有动画效果,CAAnimationGroup是个动画组,可以同时进行缩放,旋转(同时进行多个动画)。

                 CATransition是转场动画,界面之间跳转(切换)都可以用转场动画。

                 CAPropertyAnimation也是个抽象类,本身不具备动画效果,只有子类才有。

          三:

                CABasicAnimation和CAKeyframeAnimation:                 CABasicAnimation基本动画,做一些简单效果。                 CAKeyframeAnimation帧动画,做一些连续的流畅的动画。

总结学习连接:

iOS开发基础知识:Core Animation(核心动画)

详解CALayer 和 UIView的区别和联系

iOS动画学习总结

 感谢上面连接作者,有问题还是会持续更新内容!       

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏服务端技术杂谈

iOS 开发从 UIView 动画说起

毋庸置疑的:在iOS开发中,制作动画效果是最让开发者享受的环节之一。一个设计严谨、精细的动画效果能给用户耳目一新的效果,吸引他们的眼光 —— 这对于app而言是...

41770
来自专栏偏前端工程师的驿站

CSS魔法堂:Absolute Positioning就这个样

前言 当我们以position:absolute之名让元素脱离Normal flow的控制后,以为通过left和top属性值即可让元素得以无限的自由时,却发现还...

23570
来自专栏知无涯

PS给照片换背景的小技巧[易学易用]

534170
来自专栏互联网杂技

深入理解视觉格式化模型

“理论不懂就实践,实践不会就学理论”,非常赞同bluedavy的这句话。实践过程中经常会遇到某个属性的使用,浏览器渲染效果与预期效果不符,虽然通过死记硬背能避免...

36890
来自专栏非著名程序员

Android中图片大小和屏幕密度的关系讲解

Android手机适配是非常让人头疼的一件事,尤其是图片,android为了做到是适配提供了很多文件夹来存放不同大小的图片,比如:drawable-ldpi、d...

21660
来自专栏程序员互动联盟

【答疑释惑第十六讲】屏幕上的图片是如何显示出来的?

疑惑一 什么是点阵字库? 点阵字库主要用于简单的嵌入式设备,字体大小一旦选定,就不能变化。比如以前老式手机上的字,一旦选定点阵字库就不能再变化。点阵字库是一个二...

32460
来自专栏hightopo

基于 HTML5 WebGL 的 3D 场景中的灯光效果

16320
来自专栏拂晓风起

【Fanvas技术解密】HTML5 canvas实现脏区重绘

22720
来自专栏大数据钻研

手把手教你打造一个纯CSS图标库

来,干了这碗安利 写这篇文章的目的其实就是为了安利一下我的图标库:iconoo,所以,开门见山,star吧少年少妇们!(这样的我是不是应该要加个github互粉...

33540
来自专栏非著名程序员

目标:双向拖动的自定义View

国际惯例先预览后实现 ? 我们要实现的就是一个段位样式的拖动条,用来做筛选条件用的, 细心的朋友可能会发现微信设置里面有个一个通用字体的设置, 拖动然后改变字...

25060

扫码关注云+社区

领取腾讯云代金券