前言:很多動(dòng)效都是多種動(dòng)畫的組合,有時(shí)候你可能只是需要其中某個(gè)動(dòng)畫,但面對(duì)龐雜的代碼庫(kù)或是教程,你可能比較困惑,本系列將復(fù)雜動(dòng)效中不常見(jiàn)的動(dòng)畫效果拆解出來(lái)便于學(xué)習(xí),授人以魚(yú)不如授人以漁。

對(duì) TabBar 上的 TabBarItem 做漸變動(dòng)畫是個(gè)很常見(jiàn)的需求吧,應(yīng)用了這個(gè)效果的應(yīng)用里以微信最為知名,首要問(wèn)題是如何讓 TabBarItem 產(chǎn)生漸變效果。我在寫 iOS 視圖控制器轉(zhuǎn)場(chǎng)詳解這篇文章為 UITabBarController 寫轉(zhuǎn)場(chǎng)動(dòng)畫 Demo 時(shí)嘗試添加這個(gè)漸變效果。你如果了解下 TabBarItem 會(huì)發(fā)現(xiàn)這個(gè)類并沒(méi)有公開(kāi)的視圖屬性接口以便你添加動(dòng)畫,以前我也搜索過(guò)在 TabBarItem 上添加動(dòng)畫,沒(méi)有比較好的方案??戳死准冧h開(kāi)源的 WXTabBarController 后發(fā)現(xiàn),如果你不了解 TabBarItem 的內(nèi)部結(jié)構(gòu)的話,這個(gè)問(wèn)題你幾乎沒(méi)有辦法。得承認(rèn),我以前還從來(lái)沒(méi)有這么干過(guò),打開(kāi)了一片新天地。WXTabBarController 里似乎用 Reveal 來(lái)查看內(nèi)部視圖結(jié)構(gòu)的,不過(guò)我沒(méi)買這個(gè)軟件,后來(lái)想起了 Xcode 自帶的 View Debugging 功能,同樣能辦到這點(diǎn),快速入門教程:raywenderlich 家出品的 View Debugging in Xcode 6。
于是,解決方案出來(lái)了,圖勝千言:


既然掌握了內(nèi)部視圖結(jié)構(gòu),那么傳統(tǒng)的 UIView 動(dòng)畫就有用武之地了,想怎么玩都行,終于知道 Github 上那些 自定義 TabBar 的動(dòng)畫怎么來(lái)的了。
在傳統(tǒng)的 View Controller Transition(也就是所謂的轉(zhuǎn)場(chǎng))中實(shí)現(xiàn)這個(gè)效果會(huì)有一個(gè)小問(wèn)題,那就是 TabBarItem。WXTabBarController 重寫了相關(guān)的屬性方法,切斷了 UITabBarController 對(duì) TabBar 的控制,而在 UITabBarController 里,tabBar這個(gè)屬性是只讀的,對(duì) TabBarItem 的公開(kāi)接口基本不能修改,這就造成了后景偽裝圖標(biāo)的差異。
我實(shí)現(xiàn)的 SEGradualTabBarController,處理如下:

被選中的 TabBarItem 與其他 TabBarItem 的處理是相反的,切換后,切換后的 TabBarItem 也要進(jìn)行反向處理,注意下就好了。SEGradualTabBarController 與 WXTabBarController 在 TabBar 的處理上大同小異,剩下的不同就在于前者使用轉(zhuǎn)場(chǎng),后者使用 UIScrollView,這帶來(lái)了很多優(yōu)勢(shì)。
在滑動(dòng)時(shí)根據(jù)滑動(dòng)的距離來(lái)更新前后景圖標(biāo)的 alpha 值這很好理解,松手后呢?WXTabBarController 直接在 UIScrollView 的代理方法里實(shí)時(shí)更新 alpha 值:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
松手后該方法也會(huì)繼續(xù)調(diào)用直至滑動(dòng)停止,實(shí)際上 WXTabBarController 的代碼里并沒(méi)有 UIView 動(dòng)畫代碼。
SEGradualTabBarController 滑動(dòng)時(shí)在手勢(shì)綁定的方法里實(shí)時(shí)更新 alpha 值,松手后的處理......我原本是打算用CADisplayLink,在實(shí)現(xiàn)自定義容器控制器轉(zhuǎn)場(chǎng)時(shí)就是采用的這個(gè),后來(lái)發(fā)現(xiàn),都已經(jīng)有了內(nèi)部視圖了,直接使用 UIView 動(dòng)畫不就得了。在交互轉(zhuǎn)場(chǎng)里,根據(jù)松手時(shí)的閾值判斷,可以選擇完成或是取消轉(zhuǎn)場(chǎng),其中的動(dòng)畫也會(huì)同步,不過(guò)在這里行不通,看第一張圖,在子 VC 間切換時(shí), ViewController Transition 中涉及的子視圖都是 UITransitionView 的子視圖,而 TabBar 并不是 UITransitionView 的子視圖,也就無(wú)法享受 ViewController Transition 的福利了。
總體來(lái)說(shuō),在 View Controller Transition 中實(shí)現(xiàn) TabBar 的漸變效果比起 WXTabBarController 來(lái)得麻煩,后者還有個(gè)優(yōu)勢(shì)是兼容的版本更低,SEGradualTabBarController 最低只能是 iOS 7 了,不過(guò)馬上 iOS 10 都要來(lái)了。