大牛推荐:iOS 自定义下拉线条动画

移动开发 iOS
这是本章的第二个 demo,下面这个案例中,我把线条动画和数学知识结合在了一起。通过这个案例,可以很好地向你展示如何自己归纳出一个数学公式,并把它用到一个自定义动画中。

这是本章的第二个 demo,下面这个案例中,我把线条动画和数学知识结合在了一起。通过这个案例,可以很好地向你展示如何自己归纳出一个数学公式,并把它用到一个自定义动画中。

首先,我们还是先看最终效果 :


OK,可以看到随着手指在屏幕上滑动距离的改变,线条一开始逐渐靠拢,到达一定位置后开始弯曲,最终合并成了一个圆。顺便一提,我已经把这个动画封装到了一个上拉、下拉刷新的控件中,并且用在了大象公会这款独立开发的 App 中。 你可以提前下载下来一睹实际效果。

下面讲讲我是怎么思考这个动画的。首先,最终控制这个动画进度的是一个 CALayer 内部的自定义的属性:

 

  1. @property(nonatomic,assign)CGFloat progress; 

无论你是通过手指滑动产生偏移量,还是滑动 UISlider 改变一个数值,最终都将转化到这个属性的改变。然后,在这个属性的 setter 方法里,我们让 layer 去实时地重绘,就像这样:

 

  1. -(void)setProgress:(CGFloat)progress{ self.curveLayer.progress = progress; 
  2. [self.curveLayer setNeedsDisplay]; 

至于重绘的算法,属于细节上要考虑的事了。我们做一个动画的步骤都是先考虑宏观,再去考虑细节上的实现。就像开发一个 App 一样,一开始肯定是先考虑架构,再去往这个框架里添砖加瓦,修修补补。现在,我们对这个动画的整体思路已经清楚了,下面开始深入到细节去思考具体算法的实现。我把这个动画分成了两个阶段:0~0.5 和 0.5~1.0。 这是什么意思?

做动画还是那句话 ——「善于分解」。我们先看前半程,也就是 progress 从一开始的 0 运动到中间状态 0.5 的这一个阶段。这一个阶段两条线段分别从上方和下方两个方向向中间运动,直到接触到中线为止。这一阶段的画线算法非常简单,只要能实时获得 A,B 两点的坐标,剩下用 UIBezierPath 的 moveToPoint,addLineToPoint 就完事了。所以,问题转换成了求 A,B 两点运动的公式(其实只要求出一点,另一点无非就相差了一个线段长度 h)。请看演示动画(注:在电子书中是有交互动画的,但因为现在是以文章的形式呈现,所以我只能通过图片的方式向你展示)

其实你只要愿意动笔在纸上尝试推演一番,并不难求得这两个点的运动公式:

yA = H/2 + h + (1-2progress) (H/2 - h)

yB = H/2 + (1-2progress) (H/2 - h)

接下来是动画的第二阶段 0.5~1.0。这个阶段有些许复杂:「B 点保持不动,A 点继续运动到 B 的位置,同时,在顶部根据当前的进度再画出圆弧」。视觉上给人的感觉就好像尾巴在逐渐缩短,头部在慢慢弯曲。同样的,我只能以图片的形式向你展示。


在这个过程中,我们不难先求得 A 点的坐标是:

yA = H/2 + h - h(progress - 0.5) 2

比较麻烦的是这个圆弧该怎么画?答案是可以用 UIBezierPath 中提供的 - (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise NS_AVAILABLE_IOS(4_0); 这个方法绘制出圆弧。具体思路是:以 CGPointMake(self.frame.size.width/2,self.frame.size.height/2) 为圆心,10 为半径,按顺时针方向,从 M_PI(90°) 的起始角度,画到 2*M_PI 的结束角度。

关于 - (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; 方法的解释:如果设置开始角度均为 0 ,结束角度均为 π。那么设置 clockwise(顺时针) 为 YES 时,画出的是下半段圆弧;反之, 设置 clockwise(顺时针) 为 NO 时,画出的是上半段圆弧;

以上,我们只完成了一条线段的整个过程。同理,也能获得另一条线段的绘制算法。最后,别忘了线段顶端还有个箭头。绘制箭头的算法 Gallery 4.1:我们以 B 点作为箭头的起始起点,斜向左下方 30° 角延长 3 个单位。弯曲之后也同理,只需要额外加上线段转过的角度即可。


相应的代码就是:

 

  1. [arrowPath moveToPoint:pointB]; 
  2. [arrowPath addLineToPoint:CGPointMake(pointB.x - 3*(cosf(Degree)), pointB.y + 3*(sinf(Degree)))]; 
  3. [curvePath1 appendPath:arrowPath]; 

OK,这一个 demo 的分析到这里就结束了。完整代码可以在本书对应的 Github Repo:https://github.com/KittenYang/A-GUIDE-TO-iOS-ANIMATION 中下载。

关于作者:KITTEN-YANG,大四在读,目前在锤子科技做 iOS 实习。平时痴迷于交互动画,立志做一名顶尖的软件工程师兼交互设计师。您可以参观我的个人网站 http://kittenyang.com 或者来我的微博交个朋友:@KITTEN-YANG 谢谢。

责任编辑:chenqingxiang 来源: iOS开发
相关推荐

2013-06-27 11:10:01

iOS开发自定义UISlider

2011-08-09 17:16:56

CoreAnimati动画

2013-07-18 16:09:10

自定义iOS状态栏iOS开发iOS学习

2021-02-21 08:12:24

SVG线条动画Web动画

2021-09-02 10:00:42

鸿蒙HarmonyOS应用

2021-01-20 08:58:39

iOS 14桌面图标快捷指令

2011-08-02 11:17:13

iOS开发 View

2013-05-30 15:53:17

iOS开发iOS SDKPopver

2017-10-25 14:07:54

APPiOSxcode

2012-06-01 11:02:33

2015-10-14 10:54:20

iOS开发读书

2021-12-02 18:05:21

Android Interpolato动画

2012-12-24 14:42:48

iOS自定义状态栏

2015-02-12 15:33:43

微信SDK

2017-07-18 16:07:23

Drawable动画Android

2017-07-19 14:59:26

Drawable动画实现

2015-01-15 16:45:05

iOS源码自定义画图

2021-02-21 07:49:40

Web动画SVG线条动画

2015-02-12 15:38:26

微信SDK

2016-04-06 11:14:48

iOS相机自定义
点赞
收藏

51CTO技术栈公众号