iOS时钟翻转动画

3,580 阅读3分钟

我正在参加「掘金·启航计划」

最近项目有个时间倒计时的功能,网上也有很多优秀的第三方。这个功能应用还是比较广泛的,就稍微研究了一下。有好几种方法实现,笔者选取较简单一种。

原理其实很简单,就是一个的绕X轴的翻转动画,只是在翻转过程中针对特殊情况做 特殊处理就行,下面也会讲到。

效果图

fold.gif

思路

以一次完整动画为例,分步骤解析:

第一步:

新建3个UILable,分别是正在显示(currentLabel)、下一个显示(nextLabel)、做动画的(animationLabel)。

第二步:

首先在每次动画前给nextLabel设置默认的X轴起始角度翻转,这样处理是为了能够只显示上半部分,下半部分被隐藏(zPosition不改动的情况下),如下图,红色的是nextLabel,绿色的是currentLabel,灰色的是animationLabel

1.png

代码:

// 设置默认的X轴起始角度翻转,为了能够只显示上半部分,下半部分被隐藏(zPosition不改动的情况下)
func setupStartRotate() -> CATransform3D {
    var transform = CATransform3DIdentity
    transform.m34 = CGFLOAT_MIN
    transform = CATransform3DRotate(transform, .pi*kStartRotate, -1, 0, 0)
    return transform
}

第三步:

使用CADisplayLink做动画,笔者这里设置固定的刷新帧率为60(因为存在不同的刷新帧率设备),且动画执行时间0.5s,即每次刷新帧率时动画执行了2/60进度。

接下来使用CATransform3DRotateanimationLabel沿着X轴进行翻转动画,这时候我们会发现动画的进度超过一半时,会存在如下问题:

WechatIMG10.jpeg

上图这个是倒计时 2 变为 1 的过程,且动画进度超过一半时的显示画面。我们换个角度看看:

WechatIMG11.jpeg

可知在当前情况下,灰色的标签显示的是 2 的上部分的背面,但是应该显示的是 1 的下部分,这显示是有问题的。这么说有点拗口,简单来说就是一个物体在3D空间中沿X轴翻转大于90度时,我们看到的实际是物体的上下和前后均颠倒的二维平面,所以才会出现如此的不和谐。

所以解决这个问题,使动画更和谐流畅,我们需要物体翻转的动画在临界点翻转到90度时,即与屏幕垂直的时候,为了正确显示,即需要将动画的animationLabel同时沿着Y和Z轴翻转,并切换文字,将2切换成1。即:

if animateProgress >= 0.5 {
   t = CATransform3DRotate(t, .pi, 0, 0, 1);
   t = CATransform3DRotate(t, .pi, 0, 1, 0);
   animationLabel.text = nextLabel.text
 }else{
   animationLabel.text = currentLabel.text
 }

此时的过程就是 2 在翻转超过90时,将之沿着Y和Z轴翻转,并切换为1,看到的就是动图显示的过程了。

到这里一个完整的翻转动画就结束了,后面使用CADisplayLink定时重复上述动画就可以了。

后续也使用这个动画写了一个时间显示的和倒计时的demo,具体的代码在下面的链接,感兴趣的可以查阅指导下。

RCFoldAnimation

若存在什么不对的地方,欢迎指正!