iOS印象筆記交互動畫 OC完善版本

前人種樹

一直想知道 iOS 端的印象筆記(當然是老版本了,最新的印象筆記已經(jīng)放棄了這個坑人的動畫)是如何實現(xiàn)的,在網(wǎng)上搜到了這篇印象筆記交互效果(swift),UI 和效果做得都非常好。于是乎怎么也得學(xué)習(xí)學(xué)習(xí)吧,用 OC copy 一份吧。于是乎開始了踩坑之路。

首先,allsome(swift 印象筆記作者)這個 Demo,實現(xiàn)思路是首頁使用 UICollectionView 實現(xiàn),滑動時候?qū)崟r改變 cell 的 frame 實現(xiàn)類似彈簧的效果。但是, 其實這個 Demo有很多的 bug 沒有處理,但是仍然是一個很好的思路,要不是這個 Demo,估計自己怎么也寫不出這個動畫。

然后,這個 Demo 的 bug 其實并不是那么容易處理的,我特意抓取了印象筆記 7.18 版本的舊包,發(fā)現(xiàn)印象筆記原版也存在這個 bug,說不定這就是他們改版的原因呢,哈哈。

下面具體看下這個 bug,

bug.gif

造成這個 bug 的主要原因還是用了手勢,在自定義專場中使用了轉(zhuǎn)場手勢,根據(jù)手勢偏移比例可以控制轉(zhuǎn)場的進度。

熟悉轉(zhuǎn)場動畫的人應(yīng)該知道,手勢驅(qū)動有一個 bug:假如你設(shè)定,拖拽比例超過0.5,才決定完成動畫,否則取消動畫。那么當你拖拽比例是0.3的時候,那轉(zhuǎn)場動畫就進行0.3的比例,這個時候松手,轉(zhuǎn)場動畫會重新回到0,但是屏幕會閃一下。也就是轉(zhuǎn)場從0.3直接回到了0,沒有任何過渡,所以視覺上會閃一下。

等等,這個 bug 并不是每個轉(zhuǎn)場動畫都會有的,要看你怎么轉(zhuǎn)了,這句話怎么講?我在學(xué)習(xí)轉(zhuǎn)場動畫的時候看了喵神的博客里iOS7中的 VC 切換,里面的 demo 并不會因為拖拽比例不足返回時發(fā)生卡頓,效果如下

無寬高改變.gif

因為這個 Demo,在 dismiss 控制器的時候只是簡單的讓控制器 y 的值從上往下偏移了一個屏幕的距離,沒有任何寬度和高度的改變,不會觸發(fā)這個 bug。我把這個 Demo 簡單的改了一下,dismiss 的時候會同時改變控制器的寬和高,然后這個惡心的 bug 就會出現(xiàn)了


寬高改變.gif
后人完善

我在wazrx的這篇文章中找到了解決方案,那就是在手勢拖拽比例達不到我們指定的比例時,開啟一個CADisplayLink定時器不斷更新轉(zhuǎn)場的進度,比較好的解決了動畫生硬這個問題。

解決這個主要的 bug 之后,自己再把一些細枝末節(jié)完善了一下,就寫成了現(xiàn)在這個 印象筆記 OC

oc.gif
總結(jié)

簡單說一下完成印象筆記的這個Demo需要哪些知識點吧, 其實就兩個:

  1. 彈簧效果(嚴格說這個 demo 實現(xiàn)的并不是彈框效果,沒有使用到UIDynamic的性質(zhì))
  2. 自定義轉(zhuǎn)場

在寫這個 Demo 之前特意看了喵神的彈簧效果筆記。但是看到 swift 版本的 Demo 的時候發(fā)現(xiàn)原作者并沒有使用這個效果,而是在 collectionView 滑動的時候動態(tài)計算了每個 cell 的 frame,改變了每個 cell 的 y 值,從而實現(xiàn)了這個效果,不得不說非常棒!因為如果使用了 UIDynamic 實現(xiàn)彈簧效果,在點擊 cell 進入轉(zhuǎn)場動畫的時候會非?;靵y。所以原作者這個方法簡單,實用!

轉(zhuǎn)場動畫具體介紹網(wǎng)上實在太多了,可以自行百度,google。主要思想其實是: 以前怎么 modal 一個控制器是系統(tǒng)自己決定的,怎么 dismiss 也是系統(tǒng)決定的。 iOS7之后,Apple 提供了一套 API 給我們,我們可以自己決定如何 dismiss,如何 modal。

allsome的 swift 版本的 demo 中,所有轉(zhuǎn)場代理都在一個文件里,我為了讓結(jié)構(gòu)更加清晰,把轉(zhuǎn)場代理全部分開,一共三個文件。

  1. 告訴我你想如何 present 一個控制器。
  2. 告訴我你想如何 dissmiss 掉一個控制器。
  3. 告訴我你手勢驅(qū)動比例和dismiss 控制器的關(guān)系。
Snip20170510_1.png
最后的一點討論

這個 Demo 中,點擊 collectionView 的 cell,present出 MYNoteVC。
然后在使用手勢 dismiss 的時候,只要手勢開始 MYNoteVC 的 view 就被我們隱藏了,動畫效果全部在 collectionView 上完成,所以手勢沒有完成的時候開啟定時器,我們其實是對collectionView 做動畫,正因為這個特性,才能使用定時器這個技巧解決動畫生硬的問題。 如果我們直接對 MYNoteVC 做動畫的話,定時器這個技巧也不能很好的完成這個動畫,但是為什么wazrx的這篇文章的 Demo 里都沒有任何不妥呢,原因有兩個

  • wazrx 的這個 Demo 里 A -> B,B在dismiss 的時候?qū)嶋H上是對 B 的 view 的截圖進行動畫,并不是真正的 B 的 View。那印象筆記的 Demo 為什么不能對截圖做動畫呢? 因為還要實時改變控制器 title 和返回圖標的 frame 和 alpha。

  • 印象筆記的 Demo 里 A -> B, B在dismiss的時候是先隱藏 B,實際對 A 進行動畫。因為 A 和 B 長得一樣,所以并看不出來。如果 B在 dismiss 的時候就真的對 B 進行動畫,那么手勢取消的時候還是會有bug。

本文 Demo
allsome的印象筆記 Swift
wazrx轉(zhuǎn)場取消時開啟定時器文章

好像也沒什么可說的,只有動手寫了,才更明白。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容