過渡動畫可提供應(yīng)用程序界面變更的視覺反饋。 UIKit提供了一組標(biāo)準(zhǔn)過渡樣式,以便在呈現(xiàn)視圖控制器時使用,并且您可以使用自己的自定義過渡來補充標(biāo)準(zhǔn)過渡。
過渡動畫
過渡動畫將一個視圖控制器的內(nèi)容交換為另一個的內(nèi)容。 有兩種類型的過渡:呈現(xiàn)和消失。 呈現(xiàn)轉(zhuǎn)換會向應(yīng)用程序的視圖控制器層次結(jié)構(gòu)添加新的視圖控制器,而取消轉(zhuǎn)換會從層次結(jié)構(gòu)中刪除一個或多個視圖控制器。
實現(xiàn)過渡動畫需要許多對象。 UIKit提供過渡中涉及的所有對象的默認版本,你可以自定義所有對象或僅定義一個子集。 如果你選擇正確的對象集,你應(yīng)該能夠創(chuàng)建你的動畫只有少量的代碼。 即使包含交互的動畫,如果你利用UIKit提供的現(xiàn)有代碼,也可以輕松實現(xiàn)。
過渡代理
過渡代理是過渡動畫和自定義呈現(xiàn)的起點。 過渡委托是你定義的并且符合UIViewControllerTransitioningDelegate協(xié)議的對象。 它的工作是為UIKit提供以下對象:
- 動畫對象。 animator對象負責(zé)創(chuàng)建用于顯示或隱藏視圖控制器視圖的動畫。 過渡委托可以提供用于呈現(xiàn)和解除視圖控制器的單獨的動畫對象。 Animator對象符合UIViewControllerAnimatedTransitioning協(xié)議。
- 交互式動畫對象。 交互式動畫對象使用觸摸事件或手勢識別器來驅(qū)動自定義動畫的定時。 交互式動畫對象符合UIViewControllerInteractiveTransitioning協(xié)議。 創(chuàng)建交互式動畫制作最簡單的方法是將UIPercentDrivenInteractiveTransition類子類化,并向你的子類添加事件處理代碼。 該類控制使用現(xiàn)有動畫對象創(chuàng)建的動畫的時間。 如果你創(chuàng)建自己的交互式動畫師,您必須自己渲染動畫的每個幀。
- 呈現(xiàn)控制器。 呈現(xiàn)控制器管理呈現(xiàn)風(fēng)格,而視圖控制器在屏幕上。 系統(tǒng)提供了內(nèi)置呈現(xiàn)樣式的演示控制器,您可以為自己的呈現(xiàn)樣式提供自定義呈現(xiàn)控制器。
將過渡委托分配給視圖控制器的transitioningDelegate屬性會告訴UIKit你要執(zhí)行自定義過渡或呈現(xiàn)。 您的委托可以選擇性地提供哪些對象。 如果不提供animator對象,UIKit在視圖控制器的modalTransitionStyle屬性中使用標(biāo)準(zhǔn)的過渡動畫。
圖10-1顯示了過渡委托和動畫對象與提供的視圖控制器的關(guān)系。 表示控制器僅在視圖控制器的modalPresentationStyle屬性設(shè)置為UIModalPresentationCustom時使用
圖10-1自定義呈現(xiàn)和動畫對象

自定義動畫
當(dāng)呈現(xiàn)的視圖控制器的transitioningDelegate屬性包含有效對象時,UIKit使用您提供的自定義動畫對象來呈現(xiàn)視圖控制器。 當(dāng)它準(zhǔn)備一個呈現(xiàn)視圖時,UIKit調(diào)用animationControllerForPresentedController:presentingController:sourceController:方法轉(zhuǎn)換委托來檢索自定義animator對象。 如果對象可用,UIKit將執(zhí)行以下步驟:
- UIKit調(diào)用轉(zhuǎn)換委托的interactionControllerForPresentation:方法來查看交互式animator對象是否可用。 如果該方法返回nil,UIKit執(zhí)行動畫而無需用戶交互。
- UIKit調(diào)用animator對象的transitionDuration:方法來獲取動畫持續(xù)時間。
- UIKit調(diào)用適當(dāng)?shù)姆椒▉韱觿赢嫞?
- 對于非交互式動畫,UIKit會調(diào)用animator對象的animateTransition:方法。
- 對于交互式動畫,UIKit調(diào)用交互式動畫對象的startInteractiveTransition:方法。
- UIKit等待animator對象調(diào)用上下文轉(zhuǎn)換對象的completeTransition:方法。
你的自定義動畫在動畫完成之后調(diào)用此方法,通常在動畫的完成塊中。 調(diào)用這個方法結(jié)束過渡,讓UIKit知道它可以調(diào)用presentViewController的完成處理程序:animated:completion:方法,并調(diào)用animator對象自己的animationEnded:方法。
當(dāng)關(guān)閉視圖控制器時,UIKit調(diào)用您的轉(zhuǎn)換委托的animationControllerForDismissedController:方法,并執(zhí)行以下步驟:
- UIKit調(diào)用轉(zhuǎn)換委托的interactionControllerForDismissal:方法來查看交互式animator對象是否可用。 如果該方法返回nil,UIKit執(zhí)行動畫而無需用戶交互。
- UIKit調(diào)用animator對象的transitionDuration:方法來獲取動畫持續(xù)時間。
- UIKit調(diào)用適當(dāng)?shù)姆椒▉韱觿赢嫞?
- 對于非交互式動畫,UIKit會調(diào)用animator對象的animateTransition:方法。
- 對于交互式動畫,UIKit調(diào)用交互式動畫對象的startInteractiveTransition:方法。
- UIKit等待animator對象調(diào)用上下文轉(zhuǎn)換對象的completeTransition:方法。
- 你的自定義動畫在動畫完成后調(diào)用此方法,通常在動畫的完成塊中。 調(diào)用這個方法結(jié)束轉(zhuǎn)換,讓UIKit知道它可以調(diào)用presentViewController的完成處理程序:animated:completion:方法,并調(diào)用animator對象自己的animationEnded:方法。
重要
在動畫結(jié)束時調(diào)用completeTransition:方法是必需的。 UIKit不會結(jié)束轉(zhuǎn)換過
程,從而將控制權(quán)返回到您的應(yīng)用程序,直到您調(diào)用該方法。
過渡上下文對象
在過渡動畫開始之前,UIKit創(chuàng)建一個過渡上下文對象,并填充有關(guān)如何執(zhí)行動畫的信息。 過渡上下文對象是代碼的重要部分。 它實現(xiàn)UIViewControllerContextTransitioning協(xié)議,并存儲對過渡中涉及的視圖控制器和視圖的引用。 它還存儲有關(guān)如何執(zhí)行過渡的信息,包括動畫是否是交互式的。 您的animator對象需要所有這些信息來設(shè)置和執(zhí)行實際的動畫。
重要
設(shè)置自定義動畫時,請始終使用轉(zhuǎn)換上下文對象中的對象和數(shù)據(jù),而不是您自己管理的
任何緩存信息。 轉(zhuǎn)換可能發(fā)生在各種條件下,其中一些可能會更改動畫參數(shù)。 轉(zhuǎn)換
上下文對象保證具有執(zhí)行動畫所需的正確信息,而在調(diào)用動畫師方法時,緩存的信息可
能會失效。
圖10-2顯示了過渡上下文對象如何與其他對象交互。 你的animator對象在其animateTransition:方法中接收對象。 你創(chuàng)建的動畫應(yīng)該在提供的容器視圖中進行。 例如,在呈現(xiàn)視圖控制器時,將其視圖添加為容器視圖的子視圖。 容器視圖可能是窗口或常規(guī)視圖,但它始終配置為運行動畫。
圖10-2過渡上下文對象

過渡協(xié)調(diào)
對于內(nèi)置轉(zhuǎn)換和您的自定義轉(zhuǎn)換,UIKit創(chuàng)建一個轉(zhuǎn)換協(xié)調(diào)器對象,以便于您可能需要執(zhí)行的任何額外的動畫。 除了視圖控制器的呈現(xiàn)和消除之外,當(dāng)發(fā)生界面旋轉(zhuǎn)時或當(dāng)視圖控制器的框架改變時,可以發(fā)生過渡。 所有這些過渡關(guān)注對視圖層次結(jié)構(gòu)的改變。 過渡協(xié)調(diào)器是一種跟蹤這些更改并同時動畫制作您自己的內(nèi)容的方法。 要訪問過渡協(xié)調(diào)器,請獲取受影響的視圖控制器的transitionCoordinator屬性中的對象。 過渡0協(xié)調(diào)器僅存在于過渡的持續(xù)時間。
圖10-3顯示了過渡協(xié)調(diào)器與呈現(xiàn)中涉及的視圖控制器的關(guān)系。 使用過渡協(xié)調(diào)器獲取有關(guān)過渡的信息,并注冊要與過渡動畫同時執(zhí)行的動畫塊。 過渡協(xié)調(diào)器對象符合UIViewControllerTransitionCoordinatorContext協(xié)議,該協(xié)議提供定時信息,關(guān)于動畫的當(dāng)前狀態(tài)的信息,以及過渡中涉及的視圖和視圖控制器。 當(dāng)您的動畫塊被執(zhí)行時,它們類似地接收具有相同信息的上下文對象。
圖10-3過渡協(xié)調(diào)器對象

使用自定義動畫呈現(xiàn)視圖控制器
要使用自定義動畫呈現(xiàn)視圖控制器,請在現(xiàn)有視圖控制器的操作方法中執(zhí)行以下操作:
- 創(chuàng)建要顯示的視圖控制器。
- 創(chuàng)建您的自定義過渡委托對象并將其分配給視圖控制器的transitioningDelegate屬性。 過渡委托的方法應(yīng)該在提出時創(chuàng)建并返回你的自定義動畫對象。
- 調(diào)用presentViewController:animated:completion:方法來呈現(xiàn)視圖控制器。
當(dāng)調(diào)用presentViewController:animated:completion:方法時,UIKit啟動呈現(xiàn)過程。 呈現(xiàn)在下一個運行循環(huán)迭代期間開始,并繼續(xù),直到您的自定義動畫師調(diào)用completeTransition:方法。 交互式過渡允許你在過渡正在進行時處理觸摸事件,但非交互式過渡在由animator對象指定的持續(xù)時間內(nèi)運行。
實現(xiàn)Transitioning Delegate
過渡委托的目的是創(chuàng)建和返回自定義對象。 代碼清單10-1顯示了過渡方法的實現(xiàn)可以如何簡單。 此示例創(chuàng)建并返回自定義動畫對象。 大多數(shù)實際工作都是由animator對象本身處理的。
代碼清單10-1創(chuàng)建animator對象
- (id<UIViewControllerAnimatedTransitioning>)
animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting
sourceController:(UIViewController *)source {
MyAnimator* animator = [[MyAnimator alloc] init];
return animator;
}
過渡委托的其他方法可以像前面列表中的一樣簡單。 您還可以結(jié)合自定義邏輯,根據(jù)應(yīng)用程序的當(dāng)前狀態(tài)返回不同的動畫對象。
實現(xiàn)您的動畫對象
animator對象是采用UIViewControllerAnimatedTransitioning協(xié)議的任何對象。 animator對象創(chuàng)建在固定時間段內(nèi)執(zhí)行的動畫。 animator對象的關(guān)鍵是它的animateTransition:方法,您可以使用它來創(chuàng)建實際的動畫。 動畫過程大致分為以下幾個部分:
- 獲取動畫參數(shù)。
- 使用Core Animation或UIView動畫方法創(chuàng)建動畫。
- 清理并完成過渡。
獲取動畫參數(shù)
傳遞給animateTransition:方法的上下文轉(zhuǎn)換對象包含執(zhí)行動畫時要使用的數(shù)據(jù)。 從上下文轉(zhuǎn)換對象中獲取更多最新信息時,不要使用自己的緩存信息或從視圖控制器獲取信息。 提交和關(guān)閉視圖控制器有時涉及視圖控制器之外的對象。 例如,自定義呈現(xiàn)控制器可以添加背景視圖作為呈現(xiàn)視圖的一部分。 上下文過渡對象考慮了額外的視圖和對象,并為您提供了動畫的正確視圖。
- 調(diào)用viewControllerForKey:方法兩次以獲得從過渡中涉及的“從”和“到”視圖控制器從不假設(shè)你知道哪些視圖控制器參與轉(zhuǎn)換UIKit可能改變視圖控制器,同時適應(yīng)新的特性 環(huán)境或響應(yīng)你的應(yīng)用程序的請求。
- 調(diào)用containerView方法獲取動畫的superview。 將所有關(guān)鍵子視圖添加到此視圖。 例如,在呈現(xiàn)期間,將呈現(xiàn)的視圖控制器的視圖添加到此視圖。
- 調(diào)用viewForKey:方法來獲取要添加或刪除的視圖。 視圖控制器的視圖可能不是在過渡期間添加或刪除的唯一視圖。 表示控制器可能將視圖插入到層次結(jié)構(gòu)中,也必須添加或刪除。 viewForKey:方法返回包含您需要添加或刪除的所有內(nèi)容的根視圖。
- 調(diào)用finalFrameForViewController:方法來獲取要添加或刪除的視圖的最終框架矩形。
上下文轉(zhuǎn)換對象使用“from”和“to”命名法來標(biāo)識轉(zhuǎn)換中涉及的視圖控制器,視圖和框架矩形。 “從”視圖控制器總是在轉(zhuǎn)換開始時在屏幕上的視圖,并且“到”視圖控制器是其視圖在轉(zhuǎn)換結(jié)束時可見的那個。 如圖10-4所示,“from”和“to”視圖控制器在顯示和關(guān)閉之間切換位置。
圖10-4 from和to對象
交換值使得更容易編寫處理呈現(xiàn)和解除的單個動畫。 當(dāng)你設(shè)計你的動畫師時,你需要做的是包含一個屬性來知道它是動畫的演示還是解雇。 兩者之間唯一需要的區(qū)別如下:
- 對于呈現(xiàn),將“到”視圖添加到容器視圖層次結(jié)構(gòu)中。
- 對于關(guān)閉,從容器視圖層次結(jié)構(gòu)中刪除“from”視圖。
創(chuàng)建過渡動畫
在典型的呈現(xiàn)期間,將屬于呈現(xiàn)的視圖控制器的視圖動畫化到位。 其他視圖可能會作為呈現(xiàn)視圖的一部分進行動畫處理,但是動畫的主要目標(biāo)是將視圖添加到視圖層次結(jié)構(gòu)中。
當(dāng)對主視圖進行動畫處理時,您配置動畫所需的基本操作是相同的。 從過渡的上下文對象中獲取所需的對象和數(shù)據(jù),并使用該信息創(chuàng)建實際的動畫。
-
呈現(xiàn)動畫
- 使用viewControllerForKey:和viewForKey:方法來檢索過渡中涉及的視圖控制器和視圖。
- 設(shè)置“from”視圖的起始位置。 將任何其他屬性設(shè)置為其起始值。
- 從上下文過渡上下文的finalFrameForViewController:方法中獲取“to”視圖的結(jié)束位置。
- 將“to”視圖添加為容器視圖的子視圖。
- 創(chuàng)建動畫。
- 在動畫塊中,將“to”視圖動畫化到容器視圖中的最終位置。 將任何其他屬性設(shè)置為其最終值。
- 在完成塊中,調(diào)用completeTransition:方法,并執(zhí)行任何其他清理。
-
關(guān)閉動畫:
- 使用viewControllerForKey:和viewForKey:方法來檢索過渡中涉及的視圖控制器和視圖。
- 計算“from”視圖的結(jié)束位置。 此視圖屬于提交的視圖控制器,現(xiàn)在正在被關(guān)閉。
- 將“to”視圖添加為容器視圖的子視圖。在呈現(xiàn)期間,當(dāng)過渡完成時,移除屬于呈現(xiàn)視圖控制器的視圖。 因此,您必須在關(guān)閉操作期間將該視圖添加回容器。
- 創(chuàng)建動畫。
- 在動畫塊中,將“from”視圖動畫化到容器視圖中的最終位置。 將任何其他屬性設(shè)置為其最終值。
- 在完成塊中,從視圖層次結(jié)構(gòu)中刪除“from”視圖,并調(diào)用completeTransition:方法。 根據(jù)需要執(zhí)行任何其他清理。
圖10-5顯示了一個自定義的顯示和關(guān)閉過渡,動畫是它的對角視圖。 在呈現(xiàn)期間,呈現(xiàn)的視圖從屏幕開始,向上和向左對角線動畫,直到它可見。 在關(guān)閉期間,視圖反轉(zhuǎn)其方向,向下和向右動畫,直到它再次離屏。
圖10-5自定義呈現(xiàn)和關(guān)閉

代碼清單10-2顯示了如何實現(xiàn)圖10-5中所示的過渡。 檢索動畫所需的對象后,animateTransition:方法計算受影響視圖的框架矩形。 在呈現(xiàn)期間,所呈現(xiàn)的視圖由toView變量表示。 在關(guān)閉中,已解除的視圖由fromView變量表示。 presentation屬性是animator對象本身的一個自定義屬性,過渡委托在創(chuàng)建animator時設(shè)置為一個合適的值。
代碼清單10-2用于實現(xiàn)對角呈現(xiàn)和關(guān)閉的動畫
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
// Get the set of relevant objects.
UIView *containerView = [transitionContext containerView];
UIViewController *fromVC = [transitionContext
viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext
viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
// Set up some variables for the animation.
CGRect containerFrame = containerView.frame;
CGRect toViewStartFrame = [transitionContext initialFrameForViewController:toVC];
CGRect toViewFinalFrame = [transitionContext finalFrameForViewController:toVC];
CGRect fromViewFinalFrame = [transitionContext finalFrameForViewController:fromVC];
// Set up the animation parameters.
if (self.presenting) {
// Modify the frame of the presented view so that it starts
// offscreen at the lower-right corner of the container.
toViewStartFrame.origin.x = containerFrame.size.width;
toViewStartFrame.origin.y = containerFrame.size.height;
}
else {
// Modify the frame of the dismissed view so it ends in
// the lower-right corner of the container view.
fromViewFinalFrame = CGRectMake(containerFrame.size.width,
containerFrame.size.height,
toView.frame.size.width,
toView.frame.size.height);
}
// Always add the "to" view to the container.
// And it doesn't hurt to set its start frame.
[containerView addSubview:toView];
toView.frame = toViewStartFrame;
// Animate using the animator's own duration value.
[UIView animateWithDuration:[self transitionDuration:transitionContext]
animations:^{
if (self.presenting) {
// Move the presented view into position.
[toView setFrame:toViewFinalFrame];
}
else {
// Move the dismissed view offscreen.
[fromView setFrame:fromViewFinalFrame];
}
}
completion:^(BOOL finished){
BOOL success = ![transitionContext transitionWasCancelled];
// After a failed presentation or successful dismissal, remove the view.
if ((self.presenting && !success) || (!self.presenting && success)) {
[toView removeFromSuperview];
}
// Notify UIKit that the transition has finished
[transitionContext completeTransition:success];
}];
}
清理后的動畫
在過渡動畫結(jié)束時,至關(guān)重要的是調(diào)用completeTransition:方法。 調(diào)用該方法告訴UIKit轉(zhuǎn)換完成,并且用戶可以開始使用呈現(xiàn)的視圖控制器。 調(diào)用該方法也會觸發(fā)其他完成處理程序的級聯(lián),包括來自presentViewController:animated:completion:方法和animator對象自己的animationEnded:方法。 調(diào)用completeTransition:方法的最好的地方是在你的動畫塊的完成處理程序中。
因為過渡可以取消,所以您應(yīng)該使用上下文對象的transitionWasCancelled方法的返回值來確定需要清除。 取消呈現(xiàn)視圖時,您的動畫必須撤消對視圖層次結(jié)構(gòu)所做的任何修改。 關(guān)閉的成功需要類似的操作。
向你的過渡添加交互性
使動畫交互的最簡單的方法是使用UIPercentDrivenInteractiveTransition對象。 UIPercentDrivenInteractiveTransition對象與你現(xiàn)有的動畫對象配合使用,以控制其動畫的時間。 它使用你提供的完成百分比值。 所有你需要做的是設(shè)置計算完成百分比值所需的事件處理代碼,并在每個新事件到達時更新它。
您可以使用帶有或不帶有子類的UIPercentDrivenInteractiveTransition類。 如果是子類,使用子類的init方法(或startInteractiveTransition:方法)來執(zhí)行事件處理代碼的一次性設(shè)置。 之后,使用自定義事件處理代碼計算新的完成百分比值,并調(diào)用updateInteractiveTransition:方法。 當(dāng)代碼確定過渡完成時,調(diào)用finishInteractiveTransition方法。
代碼清單10-3顯示了UIPercentDrivenInteractiveTransition子類的startInteractiveTransition:方法的自定義實現(xiàn)。 此方法設(shè)置一個搖動手勢識別器來跟蹤觸摸事件,并將該手勢識別器安裝在動畫的容器視圖上。 它還保存對過渡上下文的引用以供以后使用。
代碼清單10-3配置百分比驅(qū)動交互式動畫設(shè)計器
- (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
// Always call super first.
[super startInteractiveTransition:transitionContext];
// Save the transition context for future reference.
self.contextData = transitionContext;
// Create a pan gesture recognizer to monitor events.
self.panGesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSwipeUpdate:)];
self.panGesture.maximumNumberOfTouches = 1;
// Add the gesture recognizer to the container view.
UIView* container = [transitionContext containerView];
[container addGestureRecognizer:self.panGesture];
}
手勢識別器為到達的每個新事件調(diào)用其動作方法。 您的Action方法的實現(xiàn)可以使用手勢識別器的狀態(tài)信息來確定手勢是成功,失敗還是仍在進行中。 同時,您可以使用最新的觸摸事件信息來計算手勢的新百分比值。
代碼清單10-4顯示了由代碼清單10-3中配置的平移手勢識別器調(diào)用的方法。 當(dāng)新事件到達時,該方法使用垂直行程距離來計算動畫的完成百分比。 當(dāng)手勢結(jié)束時,該方法結(jié)束過渡。
代碼清單10-4使用事件更新動畫進度
-(void)handleSwipeUpdate:(UIGestureRecognizer *)gestureRecognizer {
UIView* container = [self.contextData containerView];
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
// Reset the translation value at the beginning of the gesture.
[self.panGesture setTranslation:CGPointMake(0, 0) inView:container];
}
else if (gestureRecognizer.state == UIGestureRecognizerStateChanged) {
// Get the current translation value.
CGPoint translation = [self.panGesture translationInView:container];
// Compute how far the gesture has travelled vertically,
// relative to the height of the container view.
CGFloat percentage = fabs(translation.y / CGRectGetHeight(container.bounds));
// Use the translation value to update the interactive animator.
[self updateInteractiveTransition:percentage];
}
else if (gestureRecognizer.state >= UIGestureRecognizerStateEnded) {
// Finish the transition and remove the gesture recognizer.
[self finishInteractiveTransition];
[[self.contextData containerView] removeGestureRecognizer:self.panGesture];
}
}
注意
您計算的值表示動畫的整個長度的完成百分比。 對于交互式動畫,您可能需要避免非
線性效應(yīng),例如動畫本身中的初始速度,阻尼值和非線性完成曲線。 這種效應(yīng)傾向于
將事件的觸摸位置與任何下層視圖的移動分離。
創(chuàng)建與過渡一起運行的動畫
過渡中涉及的視圖控制器可以在任何呈現(xiàn)或過渡動畫之上執(zhí)行其他動畫。 例如,呈現(xiàn)的視圖控制器可以在過渡期間對其自己的視圖層級進行動畫化,并且在發(fā)生過渡時添加運動效果或其他視覺反饋。 任何對象都可以創(chuàng)建動畫,只要它能夠訪問呈現(xiàn)或呈現(xiàn)視圖控制器的transitionCoordinator屬性即可。 過渡協(xié)調(diào)器僅在轉(zhuǎn)換正在進行時存在。
要創(chuàng)建動畫,請調(diào)用過渡協(xié)調(diào)器的animateAlongsideTransition:completion:或animateAlongsideTransitionInView:animation:completion:方法。 您提供的塊將被存儲,直到過渡動畫開始,此時它們與其余的過渡動畫一起執(zhí)行。
呈現(xiàn)控制器與你的動畫
對于自定義呈現(xiàn),您可以提供自己的呈現(xiàn)控制器,為所呈現(xiàn)的視圖控制器提供自定義外觀。 呈現(xiàn)控制器管理與視圖控制器及其內(nèi)容分離的任何自定義。 例如,放置在視圖控制器視圖后面的調(diào)光視圖將由呈現(xiàn)控制器管理。 事實上,它不管理特定的視圖控制器的視圖意味著您可以使用相同的呈現(xiàn)控制器與您的應(yīng)用程序中的任何視圖控制器。
你從呈現(xiàn)的視圖控制器的過渡委托提供自定義的顯示控制器。 (視圖控制器的modalTransitionStyle屬性必須是UIModalPresentationCustom。)呈現(xiàn)控制器與任何動畫對象并行操作。 由于動畫師對象將視圖控制器的視圖動畫化到位,呈現(xiàn)控制器將任何附加視圖動畫化到位。 在過渡結(jié)束時,呈現(xiàn)控制器有機會對視圖層次執(zhí)行任何最終調(diào)整。