一般來說在使用 UIView.animate 要做動畫串接時,最無腦就這樣用
試想,啊如果要寫個 3 階段動畫,阿不就要接 3 層,那 3 層以上咧?哇賽那還真有點惡夢…..
當然在 open source 上已經有很多先驅寫了很多套件來處理這件事情,這篇就來嘗試自己手刻來解決。(感覺就是放假太無聊….)
好歐~先想想希望有個怎樣的套件來撰寫這類的程式,Hmmm…. 希望可以一直讓我加入動畫的設定,不用一直在那邊
UIView.animate(.....)
。好歐那就有個
add
的方法,讓我可以這樣用哇賽這樣看起來好直觀好爽啊,那就來試試看吧~
首先那個
animation
應該是某個容器吧,可以把每個動畫跟對應的設定參數放到類似佇列的結構中(這樣的用法執行起來是 FIFO),最後的 start()
就是啟動開始一個一個動畫跑吧!當然 start()
之後不能再接任何東西了….好!那就動手做這個
animation
的類別吧~ 這類別要有一個放動畫跟對應設定的陣列
陣列裡面放的就是動畫跟對應的參數設定,Hmmm….. 那就用一個內部類別來做這個結構吧!來看看
UIView.animate(.....)
這個方法到底有多少種參數宣告法!看了一下 extension 中的宣告,共有 4 種宣告的參數組合可以看到總共有
- duration: TimeInterval (必要)
- animation: () -> Void(必要)
- options: UIViewAnimationOptions(預設給
[]
) - delay: TimeInterval
- dampingRatio: CGFloat
- velocity: CGFloat
- completion: (Bool) -> Void
completion
和options
做成 optional
然後 delay
、dampingRatio
、velocity
就給預設值吧~所以這就是一個動畫的資訊類別。(options
給 optional
是因為反正一定有給預設,在 class 裡面就不先給了)好 der~ 那我們的佇列 class 目前就像這樣
好吧~有點想偷懶,那就把
add()
裡面的參數設計成大雜燴通通進來吧~而且 add()
之後還可以再次呼叫 add()
所以必須回傳自己,那 add()
就變這樣囉~一些參數就直接給預設值,這樣在呼叫時想給就給,不想給就直接用預設值,連
duration
都給預設值 1
,所以可以直接 add { // 動畫內容 }
這樣用,不想指定時間預設就是 1 秒。好啦現在所有動畫的訊息都進入
animations
陣列中了,那在 start()
中就要一個一個的拿出來執行囉!所以 start()
就這樣設計吧~OK~這樣就可以一直
add()
然後再最後來個 start()
就開始一個一個跑了。但是這樣要怎麼具體使用呢?Hmmm….. 就掛在 UIView 之下吧!
來加個 Extension
這樣在任何
ViewController
中就可以像這樣使用OK!! O…..K?????
感覺好像少了什麼!? 誒靠!我完全忘了 completion 的 callback …而且這樣用起來好像有點不足,我還想要能夠有暫停時間,就是兩個動畫中間停止個幾秒,所以最後用起來應該可以是這樣子才完整。
哇靠這樣看起來更爽更直觀~
整個執行起來就要是
1st (1 sec) -> 2nd (3 secs) -> 3rd (2 secs) -> print("pausing 3 secs") -> pause (3 secs) -> print("pause end") -> 4th (1 sec) -> print("ani end")
光想想這一堆串接要用原本的的寫法,真的會吐血啊~~~
實作細節都放在 Github 上了, 專案中還加了 Transition Queue 和 兩個混用的 Queue,要一點一點寫實在太多了, 原諒我偷懶的分享~
以上
GitHub: UIViewAnimationTransitionQueue
沒有留言:
張貼留言