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
的精确度就显得低了点,
它们还是有很大的区别的,这是我们博客园的伙伴总结的 定时器,写的很详细了,可以进去看看他们俩的区别。它们俩的创建看下面
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 创建 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!感谢作者!大家好好看看!
学完看看这个,经典的淘宝购物车效果:立即抢购图标会大致按照下面的贝塞尔曲线运动到购物车,完后消失,给大家附上大概的思路代码!代码写其实挺简单的,你完全可以试试!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | -( 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" ]; } |
1 2 3 4 | -( 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(核心动画)
感谢上面连接作者,有问题还是会持续更新内容!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话