iOS自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà)例程與需要注意的問(wèn)題
推薦 + 挑錯(cuò) + 收藏(0) + 用戶評(píng)論(0)
OS提供了一些內(nèi)置的轉(zhuǎn)場(chǎng)類型。Navigation controllers用push和pop來(lái)有層次地導(dǎo)航信息,tab bar controllers用切換tabs來(lái)在各部分之間跳轉(zhuǎn),所有的視圖控制器可以根據(jù)特定任務(wù)模態(tài)化地present和dismiss另一個(gè)視圖控制器。
API介紹
每一個(gè)自定義轉(zhuǎn)場(chǎng)涉及三個(gè)主要對(duì)象:
from view controller (消失的那個(gè))
to view controller (出現(xiàn)的那個(gè))
一個(gè)動(dòng)畫(huà)控制器
自定義轉(zhuǎn)場(chǎng)和在自定義之前一樣。對(duì)于push和pop,意味著調(diào)用UINavigationController的push-、pop-、或者set-方法來(lái)修改視圖控制器的堆棧。對(duì)于切換tabs,意味著修改UITabBarController的selectedIndex或selectedViewController屬性。對(duì)于modal,則意味著調(diào)用?[UIViewController presentViewController: animated: completion: ]或?[UIViewController dismissViewControllerAnimated: completion: ]。無(wú)論哪種情況,這個(gè)步驟都確定了“from view controller”和“to view controller”。
使用一個(gè)自定義轉(zhuǎn)場(chǎng),你需要一個(gè)動(dòng)畫(huà)控制器。對(duì)我來(lái)說(shuō)這是自定義動(dòng)畫(huà)轉(zhuǎn)場(chǎng)中最令人困惑的部分,因?yàn)槊糠N轉(zhuǎn)場(chǎng)需要的動(dòng)畫(huà)控制器不同。下表展示了如何為每種轉(zhuǎn)場(chǎng)提供動(dòng)畫(huà)控制器。記著,委托方法總是返回動(dòng)畫(huà)控制器。
動(dòng)畫(huà)控制器可以是任何遵守UIViewControllerAnimatedTransitioning協(xié)議的對(duì)象。該協(xié)議聲明了兩個(gè)必須要實(shí)現(xiàn)的方法。一個(gè)提供了動(dòng)畫(huà)的時(shí)間,另一個(gè)執(zhí)行了動(dòng)畫(huà)。這些方法調(diào)用時(shí)都傳遞一個(gè)上下文。上下文提供了入口來(lái)訪問(wèn)信息和你創(chuàng)建自定義轉(zhuǎn)場(chǎng)需要的對(duì)象。以下是一些重點(diǎn):
from view controller
to view controller
兩個(gè)視圖控制器view的第一幀和最后一幀
container view,根據(jù)這篇文檔,“作為的轉(zhuǎn)場(chǎng)中視圖的父視圖”
重要:上下文還實(shí)現(xiàn)了-completeTransition:,你必須在你自定義轉(zhuǎn)場(chǎng)結(jié)束時(shí)調(diào)用一次。
這是關(guān)于自定義轉(zhuǎn)場(chǎng)所有你需要知道的。讓我們來(lái)看一些例子!
例子
所有這些例子都可以在GitHub找到,你可以克隆這些倉(cāng)庫(kù),然后邊往下看邊試試這些例子。
這三個(gè)例子都直接或子類化地使用了TWTExampleViewController。它只是設(shè)置了視圖的背景顏色,同時(shí)使你能夠通過(guò)點(diǎn)擊任何地方來(lái)結(jié)束例子回到主菜單。
輕彈push和pop
在這個(gè)例子中,目標(biāo)是讓push和pop使用flip動(dòng)畫(huà)而不是標(biāo)準(zhǔn)的slide動(dòng)畫(huà)。一開(kāi)始我建立一個(gè)navigation controller并把TWTPushExampleViewController的實(shí)例當(dāng)作root。TWTPushExampleViewController添加了一個(gè)叫“Push”的右按鈕到導(dǎo)航欄。點(diǎn)擊它時(shí),一個(gè)新的TWTPushExampleViewController的實(shí)例被壓入navigation的堆棧:
- (void)pushButtonTapped
{
TWTPushExampleViewController *viewController = [[TWTPushExampleViewController alloc] init];
viewController.delegate = self.delegate;
[self.navigationController pushViewController:viewController animated:YES];
}
navigation controller的設(shè)置發(fā)生在TWTExamplesListViewController(運(yùn)行demo主菜單的視圖控制器)。注意,它把自己置為navigation controller的委托:
- (void)presentPushExample
{
TWTPushExampleViewController *viewController = [[TWTPushExampleViewController alloc] init];
viewController.delegate = self;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
navigationController.delegate = self;
[self presentViewController:navigationController animated:YES completion:nil];
}
這意味著當(dāng)navigation controller的轉(zhuǎn)場(chǎng)即將開(kāi)始時(shí),TWTExamplesListViewController將收到委托信息,并有機(jī)會(huì)返回一個(gè)動(dòng)畫(huà)控制器。對(duì)于這種轉(zhuǎn)場(chǎng),我使用一個(gè)TWTSimpleAnimationController的實(shí)例,它是一個(gè)+[UIView transitionFromView: toView: duration: options: completion:]的封裝:
- (id)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
TWTSimpleAnimationController *animationController = [[TWTSimpleAnimationController alloc] init];
animationController.duration = 0.5;
animationController.options = ( operation == UINavigationControllerOperationPush
??? UIViewAnimationOptionTransitionFlipFromRight
: UIViewAnimationOptionTransitionFlipFromLeft);
returnanimationController;
}
如果轉(zhuǎn)場(chǎng)是一個(gè)push,我使用一個(gè)從右側(cè)的flip,否則,我使用一個(gè)從左側(cè)的flip。
以下是TWTSimpleAnimationController的實(shí)現(xiàn):
- (NSTimeInterval)transitionDuration:(id)transitionContext
{
returnself.duration;
}
- (void)animateTransition:(id)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController];
?。踭oViewController.view layoutIfNeeded];
?。踀IView transitionFromView:fromViewController.view
toView:toViewController.view
duration:self.duration
options:self.options
completion:^(BOOL finished) {
?。踭ransitionContext completeTransition:YES];
}];
}
記著,這兩個(gè)方法是UIViewControllerAnimatedTransitioning協(xié)議的一部分。在動(dòng)畫(huà)控制器運(yùn)行自定義轉(zhuǎn)場(chǎng)的時(shí)候,它們被UIKit調(diào)用。
這里有一些關(guān)于animateTransition:需要注意的事情:
from view controller,to view controller,以及to view controller的最后一幀都從轉(zhuǎn)場(chǎng)的上下文中提取。其中還有一些其他可提取的信息,但在當(dāng)前情況下,并不需要所有信息。
+[UIView transitionFromView: toView: duration: options: completion:]負(fù)責(zé)有層次地添加和刪除視圖。在后面的例子中,我將展示一種手動(dòng)完成的情況。
在轉(zhuǎn)場(chǎng)的completion代碼塊中,我調(diào)用[transitionContext completeTransition: YES]來(lái)告訴系統(tǒng)轉(zhuǎn)場(chǎng)結(jié)束了。如果你忘了這樣做,你將無(wú)法與app交互。如果出現(xiàn)這種情況,先檢查這個(gè)原因。
以上就是全部!現(xiàn)在有一些值得嘗試的東西:
改變動(dòng)畫(huà)的持續(xù)時(shí)間來(lái)看看它如何影響navigation bar的動(dòng)畫(huà)。
把動(dòng)畫(huà)選項(xiàng)由flip改為page curls。
找一個(gè)方法讓navigation的堆棧中的每個(gè)視圖控制器能指定自己的動(dòng)畫(huà)控制器??纯丛诒疚淖詈蟮?a target='_blank' class='arckwlink_none'>推薦模式中提出的方法。
非常好我支持^.^
(0) 0%
不好我反對(duì)
(0) 0%
下載地址
iOS自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà)例程與需要注意的問(wèn)題下載
相關(guān)電子資料下載
- iOS17.1可能明天發(fā)布,iOS17.1主要修復(fù)哪些問(wèn)題? 380
- Pipeline中throwIt的用法 62
- Python怎么使用漫威庫(kù) 62
- 如何實(shí)現(xiàn)RTOS、中間件和芯片廠商API的跟蹤可觀察性? 178
- 深入探討Granite Rapids和Sierra Forest處理器架構(gòu)技術(shù) 20
- 基于OpenVINO Python API部署RT-DETR模型 107
- MaaS,云廠商在打一場(chǎng)“翻身仗” 525
- Nginx常用配置與命令 20
- 愛(ài)立信消費(fèi)者實(shí)驗(yàn)室報(bào)告:差異化的5G連接為運(yùn)營(yíng)商帶來(lái)商機(jī) 230
- 緩存的好處和類型 84