我正在参加「掘金·启航计划」
最近项目有个时间倒计时的功能,研究了一下。有好几种方法实现,笔者选取较简单一种,研究一下。
效果图
思路
以一次完整动画为例,分步骤解析:
第一步:
新建3个UILable
,分别是正在显示(currentLabel
)、下一个显示(nextLabel
)、做动画的(animationLabel
)。
第二步:
每次动画前给nextLabel
设置默认的X轴起始角度翻转,为了能够只显示上半部分,下半部分被隐藏(zPosition不改动的情况下),如下图,红色nextLabel
,绿色currentLabel
,灰色animationLabel
。
代码:
// 设置默认的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
进度。
随后animationLabel
以X轴进行翻转,动画进度超过一半,我们会发现如下问题:
这个是倒计时 2 ~ 1 的动画进度超过一半的显示。我们换个角度看看:
可知在当前情况下,灰色的标签应该显示的是 1 的下部分,而不是 2 的背面的上部分。有点拗口,简单来说就是View
沿X轴翻转大于90度后,看到的实际是上下、前后颠倒的View
,所以才会如此的不和谐。
所以为了动画和谐流畅,我们需要动画在临界点翻转90度,与屏幕垂直的时候,恢复下,即需要将动画的animationLabel
同时翻转Y和Z轴,并切换文字。即:
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
}
到这里一个完整的动画就结束了,后面定时重复上述动画就可以了。
RCFoldAnimation
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END