OneClock目前的三個表盤中使用者最喜歡的是翻頁時鐘。翻頁效果是表盤的核心,也是我花時間調試最久的細節。經過7次的産品疊代,終于調整到了一個合适的效果。
實作這個動效的方法隻需用到CABasicAnimation中的以X軸旋轉即可。CABasicAnimation實際上還有很多參數,比如大小、透明度、背景顔色等,用這個方法做很多動畫都是可以實作的。
制作翻頁時鐘的效果,實際上需要解決3個問題:
1.隻要時間刻度變動就提前翻頁;
2.真實示範出翻頁過程的遮蓋和層級效果;
3.正确顯示數字;
實作過程
将翻頁的過程通過側面角度,解析成下圖中所示的樣子。翻頁的效果是從“上半頁”翻轉到“下半頁”,為了讓過程顯得舒緩,我将翻頁的過程設定為1.0秒。翻頁過程耗時1.0秒,是以在真實時間到達某一秒鐘時,需要判斷下一秒是否需要翻頁,如果翻頁,就立刻執行翻頁的過程。
翻頁過程不需要改變最底層的X層和Y層,它們繼續靜态顯示即可。以8點13分59秒為例,當判斷下一秒為8點14分時,将立刻生成A層、B層、C層,分别在下圖示意的位置。
A層、B層所顯示的數字為目前的13,C層所顯示的數字為下一秒的時間14,當然因為方向的問題C層翻轉之後實際上是“下半層”。
一旦開始旋轉,A層、B層、C層覆寫X層和Y層,此時的X層和Y層可以提前賦予他們下一秒的時間14。
随着不斷翻轉,0.5秒後,上半層露出下一個時間14,下半層仍然顯示的是目前時間13。
0.5秒到1.0秒之間,C層會逐漸在下半部顯示,能夠清晰地看到下一個數字為14。翻頁1.0秒之後,時間剛好到達此刻的時間8點14分,A層、B層、C層的使命完成,立刻消失隐藏。X層和Y層提前1秒顯示了正确的時間,翻頁1.0秒後的時間剛好是我們所見到的正确時間8點14分。
如此,翻頁過程結束。
小時的翻頁和分鐘的翻頁實際上是一樣的,隻是小時翻頁的過程伴随着分鐘同時翻頁,例如8點59分59秒的下一秒是9點00分,是以兩個翻頁将同時進行,而基本原理是一樣的。
相關代碼
在我的代碼實作中,「翻頁時鐘」和「檢測時間」兩個函數是分開獨立的,是以時鐘、分鐘甚至秒鐘都可以單獨執行翻頁。
翻頁函數:
func rotation(A:UIView,B:UIView,C:UIView){
A.alpha = 1
B.alpha = 1
C.alpha = 1
rotationFirst(view: B)
//本文中提到的B,顯示13
rotationSecond(view: C)
//本文中提到的C,顯示14
self.perform(#selector(self.initializeABC),with: nil, afterDelay: 0.9) //最後為了過度順利,提前0.1秒讓A/B/C小時
//initializeABC函數設定A/B/C隐藏
}
func rotationFirst(view:UIView){
//舊值标簽,先出來 let animation = CABasicAnimation(keyPath: "transform.rotation.x")
animation.fromValue = (-10/360)*Double.pi
animation.toValue = (-355/360)*Double.pi
animation.duration = 1.0
animation.repeatCount = 0
animation.delegate = selfas? CAAnimationDelegate
view.layer.add(animation, forKey: "rotationSecond")
view.alpha = 1
}
func rotationSecond(view:UIView) {
//新值标簽,後 let animation = CABasicAnimation(keyPath: "transform.rotation.x")
animation.fromValue = (355/360) * Double.pi
animation.toValue = (10/360) * Double.pi
animation.duration = 1.0
animation.repeatCount = 0
animation.delegate = self as? CAAnimationDelegate
view.layer.add(animation, forKey: "rotationFirst")
view.alpha = 1
}