iOS-總結Demo--Push宜肉、Pop 匀钧、Present、Dissmiss動畫

梧桐更兼細雨谬返,到黃昏之斯、點點滴滴。這次第遣铝,怎一個佑刷、愁字了得!<愛心魚>

小結一下跳轉頁面的動畫效果實現思路酿炸!
代碼移步GitHub

總結的轉場動畫是下面幾個情況:

  • 導航控制器的 Push 動畫和 Pop 動畫
  • 普通控制器的 Present 動畫和 Dismiss動畫瘫絮,

思路簡析:

  • 跳轉的控制器遵守 UINavigationControllerDelegate 協(xié)議,從而實現 Pop 和 Push 的跳轉動畫填硕。

通過 operation == UINavigationControllerOperationPush 或者 UINavigationControllerOperationPop 區(qū)分是 Push 還是 Pop

  • (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
    animationControllerForOperation:(UINavigationControllerOperation)operation
    fromViewController:(UIViewController *)fromVC
    toViewController:(UIViewController *)toVC```
  • 跳轉的控制器遵守UIViewControllerTransitioningDelegate協(xié)議麦萤, 從而實現 Present 和 Dissmiss跳轉動畫

Present:

  • (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;

Dissmiss:

  • (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed;```
  • <big><u><b>上述的幾個方法都是 返回一個遵守UIViewControllerAnimatedTransitioning協(xié)議的對象鹿鳖,而主要的動畫實現就是寫在這個對象當中!我們只要封裝好這個類型的對象壮莹,在上述方法中返回對應實例對象就能實現動畫效果翅帜!</big></u></b>

UIViewControllerAnimatedTransitioning協(xié)議 主要實現兩個方法

-(NSTimeInterval)transitionDuration: transitionContext: 跳轉的時間
-(void)animateTransition: transitionContext 所要執(zhí)行的動畫在這里實現 ```

其中第二個方法傳入的參數是泛型的UIViewControllerContextTransitioning對象
可以通過下面它的的實例方法獲取我們需要展示動畫的相關屬性

#  這個方法獲得的是 控制整個跳轉的頁面 (API 描述:這個視圖是動畫發(fā)生的地方(畫布))(將要跳轉到的控制器的view添加到畫布上執(zhí)行動畫)
- (nullable UIView *)containerView
#  Key 取值 UITransitionContextFromViewControllerKey  (源控制器)UITransitionContextToViewControllerKey(目標控制器)
- (nullable __kindof UIViewController *)viewControllerForKey:(NSString *)key
#  Key 取值  UITransitionContextFromViewKey(源視圖)  UITransitionContextToViewKey(目標視圖)
- (nullable __kindof UIView *)viewForKey:(NSString *)key

簡單效果展示:

演示——跳轉.gif

上代碼:

第一步: 是封裝一個實現動畫的類(PP_Transition),遵循UIViewControllerAnimatedTransitioning協(xié)議

PP_Transition.h中

  • 導入 UIKit 框架

import <UIKit/UIKit.h> ```

  • 定義一個枚舉類型命满,方便我們區(qū)分場景

枚舉判斷使用場景

typedef NS_OPTIONS(NSUInteger, AnimatedScene)
{
AnimatedScenePush = 0, // 值為 0
AnimatedScenePop = 1 << 0, // 值為 2 的 0次
AnimatedScenePresent = 1 << 1, // 值為 2 的 1次
AnimatedSceneDissmiss = 1 << 2 // 值為 2 的 2次
};

- 聲明一個自定義初始化方法

>```code
- (instancetype)initWithStytle:(AnimatedScene)scene;```

-------
####PP_Transition.m中
>- 延展一個屬性 用來記錄初始化的類型

>```code
{
    AnimatedScene _scenceStyle;
}```
- 實現自定義初始化方法

>```code
- (instancetype)initWithStytle:(AnimatedScene)scene
{
    if (self = [super init])
    {
        _scenceStyle = scene;
    }
    return self;
}
  • 實現協(xié)議方法1: 轉場動畫持續(xù)時間
  • (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
    return 1.0;
    }```
  • 實現協(xié)議方法2: 具體去實現轉場的動畫 (這里我就是簡單的實現幾個動畫涝滴, 我們可以根據具體的情況加以實現)
  • 如果我們想加一些更好的效果,可以嘗試在畫布(containerView) View 上加上一些自定義的View 用來遮擋或者當做背景(比如 Pop回來時候目標View變大時候加一個背景)胶台,記住最后移除掉就行歼疮!這是一種思路!
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
   // 獲取到 containerView視圖 (我們動畫發(fā)生的載體)
   UIView *containerView = [transitionContext containerView];
   // 我們要去的 View
   UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
   // 從哪個 View 去的
   UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    switch (_scenceStyle)
   {
       case AnimatedScenePush:
       {// Push 動畫 這里只是舉個例子  動畫效果可以自己去使用
           // 注意點: 一定要把目的視圖(要去的 View) 添加到容器(containerView)上.
           [UIView animateWithDuration:1.0 animations:^{
               fromView.transform = CGAffineTransformMakeScale(0.5, 0.5);
           } completion:^(BOOL finished) {
               [containerView addSubview:toView];
               // 這個方法大概就是完成過渡動畫诈唬,更新內部視圖韩脏,控制器狀態(tài)的轉變!
               [transitionContext completeTransition:YES];
           }];
           
           NSLog(@"Push 動畫效果");
       }
          break;
       case AnimatedScenePop:
       {
           // Pop 動畫
           [UIView animateWithDuration:1.0 animations:^{
               // 讓當前的二級頁面  從下方消失
               fromView.frame = CGRectMake(0, kScreenH, kScreenW, kScreenH);
               
           } completion:^(BOOL finished) {
               
               [containerView addSubview:toView];
               
               [UIView animateWithDuration:1.0 animations:^{
                   // 讓首級頁面  由小變大
                   toView.transform = CGAffineTransformMakeScale(1, 1);
                   
               } completion:^(BOOL finished) {
                   
                   // 完成過度動畫
                   [transitionContext completeTransition:YES];
               }];
           }];
           NSLog(@"Pop 動畫效果");

       }
           
           break;
       case AnimatedScenePresent:
       {
           
           toView.frame = CGRectMake(kScreenW / 2.0 , kScreenH / 2.0, 0, 0);
           
           [containerView addSubview:toView];
           
           [UIView animateWithDuration:1.0 animations:^{
             
              toView.frame = CGRectMake(0 , 0, kScreenW, kScreenH);
           
           } completion:^(BOOL finished) {
               
               [transitionContext completeTransition:YES];
           }];
           
           NSLog(@"Present 動畫效果");
           

       }
           break;
       case AnimatedSceneDissmiss:
       {
         
           [UIView animateWithDuration:1.0 animations:^{
           // 讓當前的二級頁面  從上方消失
               fromView.frame = CGRectMake(0, -kScreenH, kScreenW, kScreenH);
               
           } completion:^(BOOL finished) {
               
               [containerView addSubview:toView];
           // 完成過度動畫
               [transitionContext completeTransition:YES];
            
           }];
           NSLog(@"Dissmiss 動畫效果");

       }
           break;
           
       default:
           break;
   }

}

在跳轉的控制器中:

  • 首先遵守<UIViewControllerTransitioningDelegate, UINavigationControllerDelegate>代理
  • 設置代理
     // 設置 導航控制器代理完成 push 和 pop
    self.navigationController.delegate = self;
     // 設置 模態(tài)轉場過渡代理
    目的控制器Vc.transitioningDelegate = self;
    目的控制器Vc.modalPresentationStyle = UIModalPresentationCustom;```

>- 代理方法實現

```code
// 導航控制器的跳轉動畫代理方法  在這里完成 Push 和 Pop 動畫
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    return operation == UINavigationControllerOperationPush ? [[PP_Transition alloc] initWithStytle:(AnimatedScenePush)] : [[PP_Transition alloc] initWithStytle:(AnimatedScenePop)];
}

// 完成轉場 Present 動畫代理
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    NSLog(@"----------->Present 一級視圖控制器中");
    return [[PP_Transition alloc] initWithStytle:(AnimatedScenePresent)];
}
// 轉場 Dissmiss 動畫 代理
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    NSLog(@"----------->Dissmiss 一級視圖控制器中");
    return [[PP_Transition alloc] initWithStytle:(AnimatedSceneDissmiss)];
}

最后說一句:

我開始寫的類名不太好铸磅, 弄了一半想改的話可以這樣!

.h選中要改的類名 ---> 菜單欄選中 Edit ---> Refactor ---> Rename

<b><big>改過之后骤素,之前用到這個類名的地方全部都換過來了</big><b>.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市愚屁,隨后出現的幾起案子,更是在濱河造成了極大的恐慌痕檬,老刑警劉巖霎槐,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異梦谜,居然都是意外死亡丘跌,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門唁桩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闭树,“玉大人,你說我怎么就攤上這事荒澡”ㄈ瑁” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵单山,是天一觀的道長碍现。 經常有香客問我,道長米奸,這世上最難降的妖魔是什么昼接? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮悴晰,結果婚禮上慢睡,老公的妹妹穿的比我還像新娘逐工。我一直安慰自己,他們只是感情好漂辐,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布泪喊。 她就那樣靜靜地躺著,像睡著了一般者吁。 火紅的嫁衣襯著肌膚如雪窘俺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天复凳,我揣著相機與錄音瘤泪,去河邊找鬼。 笑死育八,一個胖子當著我的面吹牛对途,可吹牛的內容都是我干的。 我是一名探鬼主播髓棋,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼实檀,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了按声?” 一聲冷哼從身側響起膳犹,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎签则,沒想到半個月后须床,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡渐裂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年豺旬,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柒凉。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡族阅,死狀恐怖,靈堂內的尸體忽然破棺而出膝捞,到底是詐尸還是另有隱情坦刀,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布蔬咬,位于F島的核電站求泰,受9級特大地震影響,放射性物質發(fā)生泄漏计盒。R本人自食惡果不足惜渴频,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望北启。 院中可真熱鬧卜朗,春花似錦拔第、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逛万,卻和暖如春泳猬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宇植。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工得封, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人指郁。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓忙上,卻偏偏與公主長得像,于是被迫代替她去往敵國和親闲坎。 傳聞我的和親對象是個殘疾皇子疫粥,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內容