1. 程式人生 > >自定義View Controller 轉換動畫

自定義View Controller 轉換動畫

基本概念

  • animation controller:
    • 包含執行實際動畫的程式碼
    • 代理<UIViewControllerAnimatedTransitioning>
    • -transitionDuration: 動畫時間
    • -animateTransition: 具體動畫實現
  • from view Controller:
    • 提供自定義轉場動畫animation controller
    • 代理<UIViewControllerTransitioningDelegate>
    • -(id)animationControllerForPresentedController: presentingController: sourceController:
  • to view Controller:
    • toVC.transitioningDelegate = fromVC
  • transitionContext:
    • 獲取to/from VCs,animation controller,containing UIView

建立一個定製的轉場動畫需要三步:

  1. 建立animation controller
    建立一個animation controller的類,該類實現<UIViewControllerAnimatedTransitioning> protocol,該類中包含了執行實際動畫的程式碼。
  2. 在即將轉換顯示一個view controller之前,先設定它的代理。
    該代理通常是當前顯示的view controller,當轉場到下一個view controller時,代理會收到一個獲取animation controller的回撥。
  3. 在回撥是返回animation controller

1. 建立animation controller:

@interface BouncePresentAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
@end

兩個必須的方法:

// 返回動畫時間
- (NSTimeInterval)transitionDuration:
(id <UIViewControllerContextTransitioning>)transitionContext {
return 2.0
; }
// transitionContext包含獲取to and from VC(view controller)s,the containing UIView等,相當於儲存執行動畫所需元素的集合,

// 動畫執行的方法
- (void)animateTransition:
(id <UIViewControllerContextTransitioning>)transitionContext {
    // 1. obtain state from the context
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    CGRect finalFrame = [transitionContext finalFrameForViewController:toViewController];

    // 2. obtain the container view
    UIView *containerView = [transitionContext containerView];

    // 3. set initial state
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    toViewController.view.frame =
    CGRectOffset(finalFrame, 0, screenBounds.size.height);

    // 4. add the view
    [containerView addSubview:toViewController.view];

    // 5. animate
    NSTimeInterval duration =
    [self transitionDuration:transitionContext];
    [UIView animateWithDuration:duration
        animations:^{
            toViewController.view.frame = finalFrame;
        } completion:^(BOOL finished) {
            // 6. inform the context of completion
            [transitionContext completeTransition:YES];
    }];
}

動畫執行的步驟:

  1. 使用transitionContext獲取toVC和動畫結束時該controller的view的位置

  2. 在動畫期間,to and from VCs 的 views 儲存在containerView中,需要手動將to- view加入到containerView

  3. 設定to- view的起始位置

  4. 手動將to- view加入到containerView。

  5. 開始動畫,設定to- view的結束位置(從transitionContext中獲取),動畫的時間從animation controller代理方法1中獲取。

  6. 動畫結束時,通知transitionContext,

轉場動畫整體流程圖:

轉場動畫執行流程圖

2.設定轉場動畫代理

toVC有一個transitionDelegate屬性,需要fromVC實現該代理方法。

當轉場到一個toVC時,framework會先檢查這個屬性,判斷是否執行自定義的轉場動畫。

@interface MasterViewController () <UIViewControllerTransitioningDelegate>
@end

代理(fromVC)將提供自定義轉場動畫,需要自己實現該動畫。

if ([segue.identifier isEqualToString:@"ShowAbout"]) 
{
    UIViewController *toVC = segue.destinationViewController;   toVC.transitioningDelegate = self;
}

設定toVC.transitioningDelegate的代理為fromVC。在fromVC中實現動畫實現。

在transitionDelegate(fromVC)代理中加入animation controller標頭檔案(#import “BouncePresentAnimationController.h”)和animation controller的例項變數:

@implementation MasterViewController 
{ 
    BouncePresentAnimationController *_bounceAnimationController;
}

You need to implement the UIViewControllerTransitioningDelegate method that supplies this animation controller.

需要在fromVC中自己實現UIViewControllerTransitioningDelegate的方法,該方法提供轉場的animation controller,animation controller中含有自定義轉場動畫

轉場動畫整體流程圖:

轉場動畫整體流程圖