似乎有好久都沒有更新博客了(′?_?`),十一回家的火車上看了蘋果最近更新的View Controller Programming Guide骡和,回來后忙里偷閑試驗(yàn)了自定義view controller之間的轉(zhuǎn)場(chǎng)動(dòng)畫,就寫這篇博客來記錄一下吧钦奋。
iOS系統(tǒng)本身為一個(gè)UIViewController
對(duì)象提供了這樣幾種轉(zhuǎn)場(chǎng)動(dòng)畫形式(UIModalTransitionStyle
)花鹅,分別是:
UIModalTransitionStyleCoverVertical(默認(rèn),自下而上覆蓋)
UIModalTransitionStyleFlipHorizontal(水平翻轉(zhuǎn))
UIModalTransitionStyleCrossDissolve(溶解)
UIModalTransitionStylePartialCurl(翻頁)
以前交掏,我一直以為view controller之間的轉(zhuǎn)場(chǎng)動(dòng)畫是一種神奇的存在妆偏,是因?yàn)槲覜]有意識(shí)到UITransitionView
的存在。
先寫一個(gè)特別簡(jiǎn)單的demo盅弛,就是在rootViewController上present一個(gè)UIViewController
的對(duì)象钱骂,比如這樣:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
[self presentViewController:viewController animated:YES completion:nil];
}
運(yùn)行app,等上層的view controller彈出挪鹏,用Xcode的視圖調(diào)試工具见秽,能看到這樣的視圖結(jié)構(gòu):
其中的那個(gè)UIView
,就是presentedViewController
的視圖狰住,可以發(fā)現(xiàn)张吉,它是一個(gè)UITransitionView
對(duì)象的子視圖。這個(gè)UITransitionView
對(duì)象催植,就是view controller之間轉(zhuǎn)場(chǎng)動(dòng)畫的畫布。
自定義view controller間的轉(zhuǎn)場(chǎng)動(dòng)畫
iOS7及之后版本中勺择,第三方程序員可以為自己的app設(shè)置自定義的view controller轉(zhuǎn)場(chǎng)動(dòng)畫了创南。
如果想要自定義view controller之間的轉(zhuǎn)場(chǎng)動(dòng)畫,首先要給即將展現(xiàn)的那個(gè)view controller設(shè)置transitionDelegate
省核。
這個(gè)transitionDelegate
所對(duì)應(yīng)的類需要實(shí)現(xiàn)UIViewControllerTransitioningDelegate
協(xié)議稿辙。如果只是想要自定義轉(zhuǎn)場(chǎng)動(dòng)畫,而不需要讓用戶與這個(gè)動(dòng)畫有所交互的話气忠,可以只用實(shí)現(xiàn)協(xié)議中的這兩個(gè)方法:
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
和
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed;
其中邻储,返回的對(duì)象所屬的類需要實(shí)現(xiàn)UIViewControllerAnimatedTransitioning
協(xié)議赋咽。這個(gè)類如何實(shí)現(xiàn),是自定義動(dòng)畫的關(guān)鍵吨娜。
比如我定義了一個(gè)名叫XSQAnimationObject
的類脓匿,它實(shí)現(xiàn)了UIViewControllerAnimatedTransitioning
協(xié)議。然后將它的實(shí)例對(duì)象作為上兩個(gè)方法(present和dismiss)的返回值宦赠。
在XSQAnimationObject
中陪毡,必須實(shí)現(xiàn)UIViewControllerAnimatedTransitioning
協(xié)議中的這兩個(gè)方法:
//在這個(gè)方法的實(shí)現(xiàn)中,返回轉(zhuǎn)場(chǎng)動(dòng)畫的時(shí)長(zhǎng)
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
和
//在這個(gè)方法的實(shí)現(xiàn)中勾扭,進(jìn)行轉(zhuǎn)場(chǎng)動(dòng)畫
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;
其中的transitionContext
這個(gè)參數(shù)毡琉,可以提供與對(duì)轉(zhuǎn)場(chǎng)動(dòng)畫必要的信息,比如presenting view controller妙色,presented view controller等桅滋。transitionContext
中的containerView
,便是應(yīng)該呈現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的視圖身辨。如果在運(yùn)行時(shí)打印出來丐谋,會(huì)發(fā)現(xiàn)這個(gè)containerView
是UITransitionView
的實(shí)例,其實(shí)也是最開始圖上的那個(gè)UITransitionView
栅表。
在轉(zhuǎn)場(chǎng)動(dòng)畫完成后笋鄙,一定要記得調(diào)用transitionContext
的
completeTransition:
方法。只有這樣怪瓶,presentViewController:animated:completion:
中的completion塊才能被調(diào)用萧落。
最后,自己寫了一個(gè)簡(jiǎn)單的demo洗贰,嘗試了“zoom”效果的轉(zhuǎn)場(chǎng)動(dòng)畫找岖,雖然這個(gè)效果已經(jīng)滿大街都是了,但還是放上我寫的代碼的github鏈接吧(⊙ω⊙)
參考
View Controller Programming Guide: Customizing the Transition Animations
自定義 ViewController 容器轉(zhuǎn)場(chǎng)