自定義轉(zhuǎn)場(chǎng)動(dòng)畫 push 和 pop (順帶看看present 和 dismiss))

不廢話直接上代碼属提,我們首先新建個(gè)工程,然后再創(chuàng)建一個(gè)控制器彪杉,分別給兩個(gè)控制器設(shè)置兩個(gè)背景色吧
  • 說明:我們的轉(zhuǎn)場(chǎng)自定義動(dòng)畫的代碼是寫在單獨(dú)創(chuàng)建的工具類里面的行贪,先看push的
TransPushTool.h
#import <UIKit/UIKit.h>//首先把這個(gè)頭文件要從#import <Foundation/Foundation.h>改為UIKit的
//這里是要遵守這個(gè)動(dòng)畫轉(zhuǎn)場(chǎng)的協(xié)議
@interface TransPushTool : NSObject<UIViewControllerAnimatedTransitioning>
@end

TransPushTool.m
@implementation TransPushTool
//遵守那個(gè)協(xié)議后,我們有兩個(gè)必須實(shí)現(xiàn)的方法抵代,在這里面來寫你自己想要的動(dòng)畫方式

#返回轉(zhuǎn)場(chǎng)動(dòng)畫執(zhí)行時(shí)間
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 2;
}

#利用轉(zhuǎn)場(chǎng)上下文寫動(dòng)畫
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    /**<#文檔注釋#>***
     1.transitionContext:轉(zhuǎn)場(chǎng)上下文
     2.fromVc:來自哪個(gè)ViewController
     3.toVc:去哪個(gè)控制器
     **/
//獲取view(根據(jù)key獲取view)
    UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
#我們push動(dòng)畫中用不到fromView     
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    
   #動(dòng)畫的容器:所有設(shè)置的view都必須添加到這里面來
    UIView *containerView = [transitionContext containerView];
   
    //讓要呈現(xiàn)的view透明度為0
    toView.alpha = 0;
    [containerView addSubview:toView];
    
  #寫動(dòng)畫(動(dòng)畫時(shí)間和上面的轉(zhuǎn)場(chǎng)的時(shí)間必須一樣)
    [UIView animateWithDuration:2.0 animations:^{
        toView.alpha = 1;
    } completion:^(BOOL finished) {
       //轉(zhuǎn)場(chǎng)完成
        [transitionContext completeTransition:YES];
    }];
}
#至此在這個(gè)工具類中我們做的配置已寫完了
  • 我們看看在控制器中我們還需要些那些內(nèi)容
#首先在那個(gè)ViewController.m文件中導(dǎo)入那個(gè)push動(dòng)畫工具類和下一個(gè)viewController頭文件
//我們是自定義push動(dòng)畫腾节,所以要給viewController加上導(dǎo)航控制器哦(再遵守導(dǎo)航控制器的協(xié)議)
@interface ViewController ()<UINavigationControllerDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor greenColor];
    
    //設(shè)置導(dǎo)航控制器的代理
  self.navigationController.delegate = self;
 }
//轉(zhuǎn)場(chǎng)按鈕(在storyboard中拖一個(gè)按鈕)
- (IBAction)pushBtn {
   //正常的push轉(zhuǎn)場(chǎng)就好 
    DetalViewController *vc = [[DetalViewController alloc]init];
   [self.navigationController pushViewController:vc animated:YES];
}

#pragma mark -- 實(shí)現(xiàn)導(dǎo)航控制器的代理方法
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    //判斷當(dāng)前是push還是pop
    if (operation == UINavigationControllerOperationPush)
    {
        return [[TransPushTool alloc]init];
    }else
    #如果我們寫了pop的動(dòng)畫工具類的話,這里就填pop的
        return nil;
    }
#到這里就可以實(shí)現(xiàn)那個(gè)漸變出來的push轉(zhuǎn)場(chǎng)效果了
  • 接下來我們寫個(gè)pop動(dòng)畫的工具類
TransPopTool.h
#import <UIKit/UIKit.h>
//遵守協(xié)議
@interface TransPopTool : NSObject<UIViewControllerAnimatedTransitioning>

TransPopTool.m
#import "TransPopTool.h"

@implementation TransPopTool

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 2;
}


- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
     //獲取view
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
     UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    
   //給toView的形變屬性設(shè)值(縮小一點(diǎn)點(diǎn))
    toView.transform = CGAffineTransformMakeScale(0.9, 0.9);
      UIView *containerView = [transitionContext containerView];
    
    //將toView加到FromView之下
    [containerView insertSubview:toView belowSubview:fromView];
    
    //動(dòng)畫
    [UIView animateWithDuration:2 animations:^{
      //把來自的view放到屏幕下面去
        fromView.center = CGPointMake(fromView.center.x, [UIScreen mainScreen].bounds.size.height * 2);
        //將這個(gè)恢復(fù)其形變屬性
        toView.transform = CGAffineTransformIdentity;
        
    } completion:^(BOOL finished) {
        
        [fromView removeFromSuperview];
        
        [transitionContext completeTransition:YES];
        
    }];
}
#方法和push寫動(dòng)畫是一樣的荤牍,我們?cè)趺磳?shí)現(xiàn)呢
//只需在viewControll中將導(dǎo)航控制器的代理方法那里改為
 //判斷當(dāng)前是push還是pop
    if (operation == UINavigationControllerOperationPush)
    {
        return [[TransPushTool alloc]init];
    }else
      return [[TransPopTool alloc]init];
   }

接下來我們看看那個(gè)present 和 dismiss 的轉(zhuǎn)場(chǎng)該怎么寫
  • 首先我們這兩個(gè)工具類是不用動(dòng)的案腺,我們只需在下個(gè)控制器中設(shè)置一下代碼就好(可以把導(dǎo)航的注釋掉吧)
#在要present出來的控制器的.m文件中
#import "DetalViewController.h"
//導(dǎo)入那兩個(gè)工具類的頭文件(名字可以忽略哈)
#import "TransPushTool.h"
#import "TransPopTool.h"
//遵守這樣的一個(gè)協(xié)議
@interface DetalViewController ()<UIViewControllerTransitioningDelegate>

@end
@implementation DetalViewController
- (void)viewDidLoad {
    [super viewDidLoad];
//設(shè)置代理 
 self.transitioningDelegate = self;
}
#點(diǎn)擊屏幕dismiss到上一個(gè)控制器
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
   [self  dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark -- 實(shí)現(xiàn)那個(gè)present和dismiss的代理方法
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    return [[TransPushTool alloc]init];
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    return [[TransPopTool alloc]init];
}
在viewController中我們來個(gè)present就好
//轉(zhuǎn)場(chǎng)按鈕
- (IBAction)pushBtn {
    
    DetalViewController *vc = [[DetalViewController alloc]init];
   [self presentViewController:vc animated:YES completion:nil];
}

總結(jié):上面是很簡(jiǎn)單的自定義轉(zhuǎn)場(chǎng)動(dòng)畫的兩種方式,你會(huì)發(fā)現(xiàn)只要把轉(zhuǎn)場(chǎng)的兩個(gè)工具類封裝起來康吵,以后你的push 和 pop 還有present救湖,dismiss 都可以用了。在push 和 pop 的自定義動(dòng)畫工具類可以寫成一個(gè)工具類的涎才,只需判斷一下是push 還是 pop 轉(zhuǎn)場(chǎng)
  • 網(wǎng)上有很多炫酷的轉(zhuǎn)場(chǎng)效果,感興趣可以自己去借鑒學(xué)習(xí),不過任何困難的東西都是從基礎(chǔ)來的耍铜,所以懂得基礎(chǔ)原理還是很重要的
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末邑闺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子棕兼,更是在濱河造成了極大的恐慌陡舅,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伴挚,死亡現(xiàn)場(chǎng)離奇詭異靶衍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)茎芋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門颅眶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人田弥,你說我怎么就攤上這事涛酗。” “怎么了偷厦?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵商叹,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我只泼,道長(zhǎng)剖笙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任请唱,我火速辦了婚禮弥咪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘籍滴。我一直安慰自己酪夷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布孽惰。 她就那樣靜靜地躺著晚岭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪勋功。 梳的紋絲不亂的頭發(fā)上坦报,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音狂鞋,去河邊找鬼片择。 笑死,一個(gè)胖子當(dāng)著我的面吹牛骚揍,可吹牛的內(nèi)容都是我干的字管。 我是一名探鬼主播啰挪,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼嘲叔!你這毒婦竟也來了亡呵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤硫戈,失蹤者是張志新(化名)和其女友劉穎锰什,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丁逝,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汁胆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了霜幼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嫩码。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辛掠,靈堂內(nèi)的尸體忽然破棺而出谢谦,到底是詐尸還是另有隱情,我是刑警寧澤萝衩,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布回挽,位于F島的核電站,受9級(jí)特大地震影響猩谊,放射性物質(zhì)發(fā)生泄漏千劈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一牌捷、第九天 我趴在偏房一處隱蔽的房頂上張望墙牌。 院中可真熱鬧,春花似錦暗甥、人聲如沸喜滨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)虽风。三九已至,卻和暖如春寄月,著一層夾襖步出監(jiān)牢的瞬間辜膝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工漾肮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厂抖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓克懊,卻偏偏與公主長(zhǎng)得像忱辅,于是被迫代替她去往敵國(guó)和親七蜘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容