国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

深入學習iOS7自定義導航轉場動畫

2020-07-26 03:27:56
字體:
來源:轉載
供稿:網友

在iOS7以前,開發者如果希望定制導航控制器推入推出視圖時的轉場動畫,一般都只能通過子類化UINavigationController或者自己編寫動畫代碼去覆蓋相應的方法,現在iOS7為開發者帶來了福音,蘋果公司引入了大量新API,給予了開發者很高的自由度,在處理由UIViewController管理的UIView動畫時,這些API使用方便,可擴展性也很強,定制起來非常輕松: 

  • 全新的針對UIView的動畫block方法
  • 全新的UIViewControllerAnimatedTransitioning協議以及動畫控制器的概念
  • Interaction Controllers以及Transition Coordinators
  • 全新的針對動畫的助手API(簡便方法)

全新的針對UIView的動畫block方法
iOS4的發布帶來了強大的block方法,在編寫UIView動畫時使用block可以輕松地得到滿意的效果,然而有些情況下,我們還是不得不直接使用Core Animation。幸運的是,蘋果公司在iOS7中增加了2個新的基于block的方法,這樣我們就很少再需要直接使用Core Animation了。
1、關鍵幀動畫
iOS7為UIView封裝了一組API,讓我們很容易的得到與Core Animation框架中的CAKeyframeAnimation一樣的效果。

 [UIView animateKeyframesWithDuration:duration delay:delay options:options animations:^{ [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{ //第一幀要執行的動畫 }]; [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{ //第二幀要執行的動畫 }]; } completion:^(BOOL finished) { //動畫結束后執行的代碼塊 }]; 

新引入的animateKeyframesWithDuration與CAKeyframeAnimation的關系,可以比對animateWithDuration和CABasicAnimation,我們只需要將每一幀動畫加入到block方法中,并傳入此段動畫在全過程中的相對開始時間和執行時間(duration具體是指此段動畫的執行時間占全過程的百分比)。同時,你可以在一次動畫中使用多個關鍵幀,只需使用addKeyframe依次將所有關鍵幀加入動畫執行棧中。 

下面是一個簡單的例子:在示例應用中,我使用關鍵幀block來退出模態視圖控制器。

[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.15 animations:^{ //順時針旋轉90度 snapshot.transform = CGAffineTransformMakeRotation(M_PI * -1.5); }]; [UIView addKeyframeWithRelativeStartTime:0.15 relativeDuration:0.10 animations:^{ //180度 snapshot.transform = CGAffineTransformMakeRotation(M_PI * 1.0); }]; [UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.20 animations:^{ //擺過中點,225度 snapshot.transform = CGAffineTransformMakeRotation(M_PI * 1.3); }]; [UIView addKeyframeWithRelativeStartTime:0.45 relativeDuration:0.20 animations:^{ //再擺回來,140度 snapshot.transform = CGAffineTransformMakeRotation(M_PI * 0.8); }]; [UIView addKeyframeWithRelativeStartTime:0.65 relativeDuration:0.35 animations:^{ //旋轉后掉落 //最后一步,視圖淡出并消失 CGAffineTransform shift = CGAffineTransformMakeTranslation(180.0, 0.0); CGAffineTransform rotate = CGAffineTransformMakeRotation(M_PI * 0.3); snapshot.transform = CGAffineTransformConcat(shift, rotate); _coverView.alpha = 0.0; }]; 

視圖仿佛在重力的牽引下繞左下角順時針旋轉,并在最低點擺動了一下,最后脫落。 

2、彈簧動畫
iOS7新引入的另一個block方法可以讓你輕松將真實物理世界中的彈性效果集成進視圖動畫中。蘋果公司一直建議開發者盡可能將動畫效果做的跟真實物理世界一樣――在視圖滑動時,可以像彈簧一樣,稍微拉伸一些,再彈回正確位置。使用新的彈簧動畫API來實現此效果相較以往要簡單很多。 

[UIView animateWithDuration:duration delay:delay usingSpringWithDamping:damping initialSpringVelocity:velocity options:options animations:^{ //這里書寫動畫相關代碼 } completion:^(BOOL finished) { //動畫結束后執行的代碼塊 }]; 

這里用到了一些物理上的概念:damping參數代表彈性阻尼,隨著阻尼值越來越接近0.0,動畫的彈性效果會越來越明顯,而如果設置阻尼值為1.0,則視圖動畫不會有彈性效果――視圖滑動時會直接減速到0并立刻停止,不會有彈簧類的拉伸效果。 

velocity參數代表彈性修正速度,它表示視圖在彈跳時恢復原位的速度,例如,如果在動畫中視圖被拉伸的最大距離是200像素,你想讓視圖以100像素每秒的速度恢復原位,那么就設置velocity的值為0.5。(譯者:建議大家看看源代碼,代碼中damping設置為0.8不夠明顯,你可以將damping調為0.1,然后慢慢調整velocity看看效果) 

在示例應用程序中,我用彈簧動畫讓模態視圖控制器從屏幕底部滑上來,設置彈性阻尼為0.8,彈性修正速度為1.0,運行后可以看到,視圖將沖出15像素的距離,然后慢慢降回原位。如果我設置彈性阻尼為0.6或者更小,那么視圖會沖得更高,而且降回原位前還會繼續向下反彈。(也就是停止前來回彈的次數越來越多,彈性效果越來越明顯)需要注意的是,不要將彈性動畫與UIKit的動態特效引擎相混淆。彈性動畫是一個標準的UIView動畫API,僅僅提供了有限的幾種真實物理效果。 

自定義UIViewController的轉場動畫
現在讓我們來看一個好東西。蘋果公司不僅為開發者引入了新的動畫API,而且還擴大了其應用范圍。在使用UIViewController管理視圖的推入推出時,可以很容易地自定義以下轉場動畫:

• UIViewController
• presentViewController
• UITabBarController
• setSelectedViewController
• setSelectedIndex
• UINavigationController
• pushViewController
• popViewController
• setViewControllers 

在示例應用程序中,我創建了一系列轉場動畫,在動畫中使用了之前講解過的新引入的彈簧動畫和關鍵幀block方法,現在讓我們來看看如何使用新API來自定義上述的轉場動畫。
1、核心概念:動畫控制器
那么,如何在使用自定義動畫的同時不影響視圖的其他屬性?對此蘋果公司提供了一個新的協議:UIViewControllerAnimatedTransitioning,我們可以在協議方法中編寫自定義的動畫代碼。蘋果開發者文檔中稱實現了此協議的對象為動畫控制器。 
由于我們使用了協議這一語法特性,自定義動畫的代碼可以靈活的放在自己想要的位置。你可以創建一個專門用于管理動畫的類, 也可以讓UIViewController實現UIViewControllerAnimatedTransitioning接口。由于需要實現一系列不同的動畫,因此選擇為每個動畫創建一個類。接下來創建這些動畫類的通用父類――BaseAnimation,它定義了一些通用的屬性和助手方法。
讓我們來看第一個動畫,使用UINavigationController推入推出視圖時,會有一個簡單的縮放效果。

-(void)animateTransition: (id)transitionContext { //獲取容器視圖引用 UIView *containerView = [transitionContext containerView]; UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey ]; UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; if (self.type == AnimationTypePresent) { //插入“to”視圖,初始縮放值為0.0 toViewController.view.transform = CGAffineTransformMakeScale(0.0, 0.0); [containerView insertSubview:toViewController.view aboveSubview:fromViewController.view]; //縮放“to”視圖為想要的效果 [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ toViewController.view.transform = CGAffineTransformMakeScale(1.0, 1.0); } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } else if (self.type == AnimationTypeDismiss) { //插入“to”視圖 [containerView insertSubview:toViewController.view belowSubview:fromViewController.view]; //縮小“from”視圖,直到其消失 [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ fromViewController.view.transform = CGAffineTransformMakeScale(0.0, 0.0); } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } } -(NSTimeInterval)transitionDuration: (id)transitionContext { return 0.4; } 

符合UIViewControllerAnimatedTransitioning協議的任何對象都需要實現animateTransition:和transitionDuration:兩個方法。你也可以選擇實現@optional方法animationEnded:,它在動畫完成后由系統自動調用,相當于completion block,非常方便。
 在animateTransition:中你需要處理以下過程:
1. 將“to”視圖插入容器視圖
2. 將“to”和“from”視圖分別移動到自己想要的位置
3. 最后,在動畫完成時千萬別忘了調用completeTransition: 方法
UIViewControllerAnimatedTransitioning協議中的方法都帶有一個參數:transitionContext,這是一個系統級的對象,它符合 UIView-ControllerContextTransitioning協議,我們可以從該對象中獲取用于控制轉場動畫的必要信息,主要包括以下內容:

 顯然,蘋果公司幫助開發者完成了大部分讓人討厭的細節工作,僅僅需要我們自己完成的工作就是定義動畫的初始狀態和終止狀態,并調整到自己滿意的效果。最后我再

主站蜘蛛池模板: 广南县| 临海市| 泌阳县| 嘉黎县| 嵊州市| 海安县| 修水县| 宣化县| 松潘县| 漳平市| 比如县| 阿图什市| 晴隆县| 榆社县| 来安县| 太白县| 托里县| 封开县| 且末县| 前郭尔| 凌源市| 徐闻县| 朝阳市| 隆德县| 休宁县| 平安县| 蒲江县| 安庆市| 永顺县| 苗栗县| 邯郸市| 辽阳县| 赞皇县| 铁岭县| 陆良县| 九台市| 广西| 界首市| 玛曲县| 南江县| 昂仁县|