你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 一款Loading動畫的實現思路(四·完結篇)

一款Loading動畫的實現思路(四·完結篇)

編輯:IOS開發基礎

感謝大家對前幾篇的支持,這一篇,我們一鼓作氣,把整個動畫完成。

慣例,為了方便第一次來的同學,我先貼一下動畫完成的效果圖:

1013170-91389ecfed05069b.gif

實現階段4時,我們用了一種處理問題的方式,大約是這樣的:

描述問題,直到足夠清晰,

把問題分解成一組小問題,

利用經驗處理可以解決的問題,

經驗無法解決的問題,我們去調研,調研結果會成為我們下次的經驗。

階段5中,我們再應用一下這個方式(有疑惑的同學可以戳第三篇)。

先來看一下階段5的效果圖,

慣例,前幾個階段的動畫我們用灰色快速表示,當前階段使用彩色慢速表示,如圖:

1013170-0ef0f7924406cb07.gif

階段5

看上去比階段4還要復雜,別急,我們來描述一下:

一開始圓是扁的,圓裡面有一條粗線,粗線的頂部和圓的頂部連在一起,

圓漸漸恢復原狀,同時粗線漸漸變長,連到了圓的底部,與此同時,粗線的某處出現了兩條線,分別向左下、右下延伸,漸漸連到了圓上。

很粗糙,但基本上描述出了這個階段。

上文中我加黑了部分文字,這些文字很有標志性(有的平台轉載時看不到加黑,可以戳原文查看)

“一開始”,指示出了本階段動畫的初始階段

“漸漸”,指示出了動畫

“同時”、“分別”,指示出了本階段中可以拆分出的子動畫

由此我們可以得到下面的描述:

初始:

圓:扁的

粗線:頂部和圓頂部連著,底部不連著

左下線:看不到

右下線:看不到

動畫:

圓:恢復到正常的形狀

粗線:變長

左下線:出現並變長

右下線:出現並變長

結束:

圓:正常的形狀

粗線:頂點、底點分別與圓的頂點、底點連著

左下線:起點在粗線上,終點在圓上

右下線:起點在粗線上,終點在圓上

和前面的描述相比,這個描述形式化了,雖然還比較粗略,但已經清晰的標明動畫被拆分成了4部分,各部分的初始及結束狀態也有了。

我們給4部分染上不同的顏色看一下:

1013170-7e3603b856f59843.gif

階段5 多彩版

是不是比之前的清晰多了,

描述問題和分解問題,到這裡我們就完成了。

接下來就是思考動畫的方案了:

圓:階段4中是執行transform.scale.y動畫變扁了,本階段將transform恢復為CATransform3DIdentity就可以了;

粗線:階段4中是從無成長到一定長度,用的stroke方案(想了解stroke方案的同學請戳第二篇),這個階段就是繼續變長,沿用stroke方案就可以了;

左下線、右下線:本質是一樣,從無成長到一定長度,類比粗線可知,可以使用stroke方案;

這些方案都是以前的經驗,階段5可以不用調研了。

接下來就是找關鍵的節點值了:

對於一個動畫來講,關鍵的節點就是初始狀態和結束狀態,前幾篇中我們一起找過了關鍵的節點值,相信大家已經有感覺了,本文我們就不再找了。

我們一起來看一下階段5中特殊的地方:

前文中說到粗線時,我說的是繼續變長

繼續聽上去就有延續的意思,看上去,粗線兩個階段的動畫可以合並成一個。

回憶一下,階段4中粗線的path起點是圓未變形時的頂點,終點是圓未變形時的圓心,strokeEnd是從path起點逐漸stroke到path的終點,如下圖(灰色是path,藍色是stroke,SS、SE是初始,SS'、SE'是結束):

1013170-b17593231173032f.png

階段4 粗線

結合階段5,我們可以將path的終點修改為圓的底點,這樣一來,就將階段4的strokeEnd修改為從path的起點stroke到path的1/2處,如下圖:

1013170-4b2b1713a849a196.png

新階段4 粗線

而階段5的strokeEnd就是在階段4的基礎上繼續stroke到path的終點,這樣兩個階段的動畫就合到一起了,如下圖:

1013170-25f34d2fe196821d.png

階段5 粗線

有的同學可能會說,早知道是這樣,一開始就這樣寫就可以了。

這麼說的是有道理的,有的人習慣這樣,先分階段考慮,再整體看一下各階段,該合並的合並,該修改的修改,方案成形,最後寫代碼,這是個很好的方式。

然而對我來說,階段性的成就感很重要,每當我看到一個階段的動畫在我眼前動起來,感覺都很爽,所以我還是習慣於逐個階段的實現,有需要時重構前面的階段,只要邏輯清晰,重構起來問題不大。

每個人都能找到最適合自己的方式,這本身就是一種樂趣。

好了,階段5我們聊了很多,後面的階段我們就簡要的說一下了。

從完整的效果圖可知,這個動畫是有成功和失敗兩個狀態的,因此我們分開來看。

成功狀態,從階段5到階段6_success:

1013170-87f313ef33c8fc4e.gif

階段6_success

描述一下:

圓變色

對號漸漸出現(stroke)

失敗狀態,先是從階段3直接到階段6_fail:

1013170-24be76bab2920d6b.gif

階段6_fail

描述一下:

圓變色

歎號的上半部分漸漸出現(stroke)

歎號的下半部分漸漸出現(stroke)

然後從階段6_fail到階段7_fail:

1013170-1c61eafc7e9bd078.gif

階段7_fail

描述一下:

歎號繞圓心左右晃幾下(rotate)

階段7_fail要簡單的說一下:

在階段6_fail中,歎號被拆分成了上下兩個layer,而在階段7_fail中兩者又是作為一個整體動的,我們要讓它們分別執行動畫麼?

不是的,一個獨立的動畫應該只涉及一個對象,兩個layer有共同的superLayer,讓superLayer執行動畫就可以了,假如superLayer還有其他subLayer,不方便執行動畫,我們在兩個layer和superLayer中間插入一層專門執行動畫的layer就可以了。

到這裡,我們的動畫就完成了,完整代碼請移步GitHub上的OneLoadingAnimation工程。

在結束之前,我們簡單說一下階段1另一種思路(想看看階段1的同學請戳第一篇),這個思路更符合直覺,這個思路是受簡友YouXianMing在第一篇中的評論啟發,感謝。

先回憶一下階段1的樣子:

1013170-228fab8451cd6704.gif

階段1

描述一下:

圓從不完整漸漸變到完整(stroke)

圓在漸漸旋轉(rotate)

由此我們得出,一個圓同時執行stroke和rotate動畫就可以了,下面是示意代碼

// 不完整的示意代碼
- (void)doStep1 {
    // 不用自定義layer了
    self.arcToCircleLayer = [CAShapeLayer layer]; 
    // stroke動畫
    CABasicAnimation *ssAnima = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
    CABasicAnimation *seAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    // rotate動畫
    CABasicAnimation *rotateAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    // 同時執行
    CAAnimationGroup *animation = [CAAnimationGroup animation];
    animation.animations = @[ssAnima, seAnima, rotateAnima];
}

是不是比第一篇的實現方式更清晰,

我們也可以看到,問題分解後,局部的優化也比較方便,

這部分的完整代碼我放到了工程的OneLoadingAnimationStep1Another目錄下。

有的同學還記得,我們這是一個簡化的版本,階段4中原動效中圓的不規則變形被我處理成了規則變形,

為了思路不被卡住,我選擇了暫時簡化,完成之後,我們可以再去優化。

為了彌補這個缺憾,我會開一個外篇,專門聊一下圓不規則變形的實現,歡迎大家到時來捧場;

另,有簡友在簡信中提到了Swift,因此我寫了一個Swift版的實現,放在了工程的OneLoadingAnimationCompleteSwift目錄下,由於我的Swift水平不夠,代碼裡還有坑,僅供參考。

本系列的主線到這就完結了,非常感謝大家的捧場!

完整代碼

請參考GitHub上OneLoadingAnimation工程。

本系列的傳送門

  • 一款Loading動畫的實現思路(一)

  • 一款Loading動畫的實現思路(二)

  • 一款Loading動畫的實現思路(三)

  • 一款Loading動畫的實現思路(四·完結篇)

鳴謝及推薦

  • 原動效的設計者 moonjoin

  • 優秀的動效教程 Kitten's 時間膠囊

  • 喵神發起的objc中國的動畫部分,都是很優秀的譯文,衷心為翻譯的同學點贊。

相關鏈接

  • Core Animation Programming Guide

  • CALayer Class Reference

  • CAShapeLayer Class Reference

  • UIBezierPath Class Reference

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved