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分,因此兩個翻頁將同時進行,而基本原理是一樣的。
相關程式碼
在我的程式碼實現中,「翻頁時鐘」和「檢測時間」兩個函式是分開獨立的,因此時鐘、分鐘甚至秒鐘都可以單獨執行翻頁。
最後,分享出OneClock的下載連結和翻頁函式的具體Swift程式碼:
OneClock下載:https://itunes.apple.com/cn/app/id1257395357
翻頁函式:
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
}
複製程式碼
GitHub:OneSwift - iOS Tips Based On Swift
微博:xDEHANG