在系統並深入學習iOS動畫的過程中,不得不說是個痛苦的過程。沒有任何書系統的講解這方面的知識,網上的文章都講的支離破碎;很幸運的看到了http://objccn.io這個網站;即使如此,還是花了三天時間;這個是對整體概念模糊到不斷清晰,再逐步理順,最後總結歸納為幾個關鍵點。我想這輩子應該都忘記不了了。
iOS上的動畫效果絕對贊;最常見的uitable動態效果,當手指在屏幕上下滑動時,列表會跟隨其一起上下活動;如果猛的往上一推,還可以看到列表的慣性作用下,還會不斷滾動,同時慢慢減速。這個過程根本不需要我們寫一行代碼。我們用“animat”作為關鍵在工程中搜索一下,就會明白我們是多麼頻繁的,直接或間接的在使用動畫效果。
在UIViewController,UICollectionView,UIView,CALayer中使用動畫
在push和pop視圖控制器的時候,就有一個animated的選項。甚至從iOS7開始允許開發者自定義視圖轉場效果,具體來說,你可以定義pop和push時的動畫效果,還可以定義子視圖控制之間切換時的動畫效果。對於子視圖之間切換效果也可以用之前的transitionFromViewController:toViewController:duration:options:animations:completion:。具體看自定義ViewController容器轉場 ,以及View Controller轉場 。
UICollectionView是個比UITableView更靈活的組件,當然使用起來也更復雜;iOS7開始,為其定制了更炫的動畫效果。更具體的內容見:Collection View動畫 。
UIView的動畫是最常見的了,iOS4之前的調用方式:
[UIViewbeginAnimations:nilcontext:NULL];
[UIViewsetAnimationDuration:0.3];
// Set the new transform
self.view.layer.affineTransform=newTransform;
// Fix the view origin
self.view.frame= (CGRect){ { f.origin.x, f.origin.y},self.view.frame.size};
[UIViewcommitAnimations];
現在都用block的方式進行調用:
[UIViewanimateWithDuration:0.3animations:^{
UIEdgeInsetsinsets =
scrollView.scrollIndicatorInsets;
//insets.top = kStatusBarHeight;
insets.bottom=52;
scrollView.scrollIndicatorInsets= insets;
[self.viewlayoutIfNeeded];
}];
所有的動畫實現,歸根結底都是基於CALayer,調用方式如下,更多請見動畫解釋 :
CAKeyframeAnimation*anim = [CAKeyframeAnimationanimationWithKeyPath:@transform.rotation];
anim.values= forward ?@[@0,@(M_PI)]:@[@(M_PI),@0];
[indicatoraddAnimation:animforKey:anim.keyPath];
CALayer是基於了Core Animation之上;而從iOS7開始,提供了更加有趣的模擬物理世界動態的框架,UIKit Dynamics。
隱式動畫vs顯式動畫
當改變CALayer的某個屬性如x坐標,默認就會產生動畫效果,這就是隱式動畫;你可以使用矩陣變化CGAffineTransform*實現更復雜的外形變化的效果。顯式動畫就是類似如下代碼:
[indicatoraddAnimation:animforKey:anim.keyPath];
關於它們的更詳細解釋請見,Layer中自定義屬性的動畫
UIView是如何和CALayer進行協作的:
UIView其實是CALayer的一個的代理,也就說我們看到界面上的東西,其實還是由CALayer來負責展示。CALayer是有隱形動畫,可是為什麼我們修改一個UIView的外形時,沒有看到動態效果。詳細的解釋請看,View-Layer協作
交互式動畫技術的實現
交互式動畫的特點是隨時響應外部的觸控時間;這包含兩方面:
1,隨手勢而動:當我們向右側滑動時,可以看到上層頁面逐步向右推,下層頁面逐步顯示出來;如果繼續往右邊滑動時,到一定程度上層頁面完全消失,而下層頁面完全顯示出來。但也有可能性,用戶往回滑動,下層頁面又回到了之前的位置。
2,隨時撤銷動畫:這是就比較復雜了。比方我們一個方塊從左到右滑動,滑動到一半,我們想撤回讓方塊回到原來位置;雖然我們可以撤銷動畫,但是看到的效果是;突然方塊出現在了原來位置,而不是從現在的位置被拖回來。要完美實現動畫撤銷的效果就得理解,Present layer/Model Layer,Present Layer用於保存圖層的實時屬性,與當前動畫進行有關,而Model Layer只是保持了最終屬性值。所以解決方案是,在撤回時獲取其實時屬性,在添加其返回的動畫。詳見:交互式動畫 。當然我們也可以使用Pop框架,它是完全的交互動畫框架。
總結:
照例總結一下,學習就是先把書讀厚,然後再把書讀薄的過程:
1,Core Animation是iOS上動畫的關鍵人物;所有看到CA*的類,一定和動畫有關,比方CALayer。
2,只要改變CALayer的動畫相關屬性,比方位置,大小就會觸發隱性動畫。UIView是CALayer的代理而已,所有也天然有隱形動畫,觸發的方式就是動畫屬性的變化代碼放到類似animateWithDuration的block中。
3,位置,大小,外形,顏色,透明度都是動畫屬性。
學的越多,做的越快;學的越多,做的越好。