【iOS】STLoadingGroup-知乎日報加載動畫
這段時間在看 ray 的 《iOS Animation by Tutorials》 這本書,把以前完全不熟悉的動畫學習了下。然后動手嘗試了一些簡單的加載動畫。本文總結一基礎動畫的分析過程和實現。
Github :
https://github.com/saitjr/STLoadingGroup
</div>環境信息:
Mac OS X 10.11.2
Xcode 7.2
iOS 9.2
Swift 2
正文:
一、慢動作效果
二、拆分與組合
動畫一共可以拆分成三個部分:
- 白線開始繪制,逐漸形成圓( aniamtion-1 )
- 白線的起始點變化,追上之前繪制的線,圓環逐漸消失( animation-2 )
- 每次出現的起點順時針旋轉了 1/4 個圓( animation-3 ) </ol>
-
animation-1和 animation-2 的 duration 相同(如果一定要糾結,其實看到的效果 animation-2 應該會比 animation-1 后執行,因為 animation-2 是快速追上 animation-1 的,但這可以通過設置 CABasicAnimation 的 fromValue 來處理成同時執行,詳見 《iOS Animation by Tutorials》的 Chapter 15 Stoke and Path Animations )。
</li> - 三個動畫 repeatCount 相同。都是無限循環,可以將 repeatCount 設置為 Float.infinity 來達到效果。
- 執行動畫的對象相同,均作用在同一個 layer。 </ol>
- 圓環起點和終點的控制,需要用到 stokeEnd 和 stokeStart 屬性。
-
不需要響應用戶交互事件。
</li> - 需要設置線寬、背景色、線頭尾的圓角樣式。 </ul>
這三個動畫的共同點:
三、選擇
1.選擇作用對象
關于選用 UIView , CALayer 還是 CAShapeLayer ,首先需要清楚他們的特點和當前需求的符合度。
需求:根據上面的分析,我們需要對象有以下特點:
雖然使用 UIView 的 darwRect 方法也能達到效果。但是 UIView 為 layer 的管理者,并且可以捕捉事件(當然這只是其中一個特點)。這一特點我們明顯不需要。所以,選擇 CAShapeLayer 來實現。
2.選擇動畫
既然選擇了 layer,那么動畫肯定選擇 CA 開頭的類。其中 CAAnimation 、 CABasicAnimation 、 CAKeyframeAnimation 等動畫都有自己的特點。 因為只需要簡單的控制 stokeEnd 與 stokeStart ,所以 CABasicAnimation 已經能滿足要求。
四、實現
1.繪制圓環路徑
cycleLayer.lineCap = kCALineCapRound // 設置圓角 cycleLayer.lineJoin = kCALineJoinRound // 設置圓角 cycleLayer.lineWidth = STConfiguration.LineWidth // LineWidth 是提前定義的線寬常量 cycleLayer.fillColor = UIColor.clearColor().CGColor cycleLayer.strokeColor = STConfiguration.MainColor.CGColor // MainColor 是提前定義的主題色常量 cycleLayer.strokeEnd = 0 layer.addSublayer(cycleLayer)
以上代碼分別設置了圓環 layer 的圓角、線寬、填充色(透明)、邊框色( MainColor )、初始化終點位置。
對于一條線的繪制,需要的就是起點和終點。iOS 中,控制這兩個點分別是 stokeEnd 和 stokeStart 屬性。所以最初終點 stokeEnd = 0 。
2.動畫
先來看看更改起點和終點動畫的慢動作效果,然后再根據之前的分析,做動畫。
其中,控制兩個點的 stokeEnd 和 stokeStart 分別位于:
所以,先對 stokeEnd 進行動畫,隨后 stokeStart 追上它。這個“隨后”怎么處理呢?最直觀的就是延遲,設置動畫的 beginTime ,但是這里沒必要。 stokeStart 和 stokeEnd 的有效值均為 0 ~ 1, 所以,想要有延遲的效果,將動畫的 fromValue 設置為負值開始即可。具體負多少,就要看 stokeStart 什么時候追上 stokeEnd 了。
let strokeStartAnimation = CABasicAnimation(keyPath: "strokeStart") strokeStartAnimation.fromValue = -1 strokeStartAnimation.toValue = 1.0let strokeEndAnimation = CABasicAnimation(keyPath: "strokeEnd") strokeEndAnimation.fromValue = 0 strokeEndAnimation.toValue = 1.0
let animationGroup = CAAnimationGroup() animationGroup.duration = STConfiguration.AnimationDuration // 動畫時長是提前定義的常量 animationGroup.repeatCount = Float.infinity animationGroup.animations = [strokeStartAnimation, strokeEndAnimation] cycleLayer.addAnimation(animationGroup, forKey: "animationGroup")</pre>
最后,是旋轉動畫。在畫線的過程中,同時也在做旋轉,所以每次 stokeStart 開始的地方才改變了。再來看一下效果:
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation") rotateAnimation.fromValue = 0 rotateAnimation.toValue = M_PI * 2 rotateAnimation.repeatCount = Float.infinity rotateAnimation.duration = STConfiguration.AnimationDuration * 4 cycleLayer.addAnimation(rotateAnimation, forKey: "rotateAnimation")圓環繪制一圈,要變 1/4 個角度,所以, 旋轉一圈需要 4 * 繪制一圈的時長。
到此,這個動畫最關鍵的部分就完成了。其他邏輯下載源碼進行查看 :
https://github.com/saitjr/STLoadingGroup
</div> </article>來自: http://www.saitjr.com/ios/ios-stloadinggroup-zhihu-load-animation.html
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!