UIKETフレームワーク(10)カスタムmodal遷移効果

4851 ワード

前の記事ではmodal方式のページ切り替えについて説明しました
カスタムの目的コントローラmodal切り替え時にソースコントローラを完全に上書きするには、カスタムの移行効果を実現する方法について説明します.
実装された効果の説明:
目的コントローラ:画面の2分の1の大きさを占め、中央に位置し、ソースコントローラにシャドウ効果を上書きし、シャドウをクリックすると目的コントローラが戻ります.
  • UIPresentationController

  • 目的コントローラがmodalで切り替える遷移効果を説明するために使用します
    サブクラスを実装し、特殊な効果をカスタマイズできます.
    実装手順:
  • 遷移効果の定義:UIpresentationControllerサブクラス
  • の実装
  • 目的コントローラ、遷移プロトコルに従い、遷移コントローラオブジェクト
  • を設定する
  • ソースコントローラによるmodal切替
  • UIpresentationControlのプロパティ:
    @property(nonatomic, retain, readonly) UIViewController *presentedViewController   // 
    @property(nonatomic, retain, readonly) UIViewController*presentingViewController   // 
    - (UIView *)presentedView  // view
         @property(nonatomic, readonly) UIView *containerView  // view
  • UIpresentationControllerのサブクラスを書き換える方法
  • 1)initメソッド、他の補助遷移効果のviewを作成できる
    - (instancetype)initWithPresentedViewController:(UIViewController*)presentedViewController presentingViewController:(UIViewController*)presentingViewController

    次のようになります.
    - (instancetype)initWithPresentedViewController:(UIViewController*)presentedViewController presentingViewController:(UIViewController*)presentingViewController {    
        if ( self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController] ) {
            _shadowBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            // 
            _shadowBtn.backgroundColor = [UIColor grayColor];
            _shadowBtn.alpha = 0.f;
        }
    }

    2)presentationTransitionWillbeginメソッドを書き換え、移行効果の実現を定義する
    - (void)presentationTransitionWillBegin

    次のようになります.
    - (void)presentationTransitionWillBegin
    {
        [self.containerView addSubview:_shadowBtn];
        [self.containerView addSubview:self.presentedView];
        _shadowBtn.frame = self.containerView.bounds;
        id <UIViewControllerTransitionCoordinator> coordinate = self.presetingViewController.transitionCoordinator;
        [coordinate animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
            _shadowBtn.alpha = 0.5;
        } completion:nil];
    }

    UIViewControllerへのtransitionCoordinatorを使用して、遷移効果を表すアシスタント
    アシスタントのanimateAlongsideTransitionメソッドは、遷移中のアニメーション効果を定義します.
    3)presentationTransitionDidEndメソッドを書き換え,遷移効果を定義した後のクリーンアップ作業.
    特に遷移未完了時のクリーンアップ動作
    - (void)presentationTransitionDidEnd:(BOOL)completed
    - (void)presentationTransitionDidEnd:(BOOL)completed
    {
        if ( !completed ) {
            [_shadowBtn removeFromSuperview];
        }
    }

    4)frameOfPresentedViewInContainerViewを書き換え、表示されるビューのframeを設定する
    - (CGRect)frameOfPresentedViewInContainerView
    - (CGRect)frameOfPresentedViewInContainerView
    {
        CGFloat x, y, w, h;
        w = self.containerView.frame.size.width/2;
        h = self.containerView.frame.size.height/2;
        x = self.containerView.frame.size.width/4;
        y = self.containerView.frame.size.height/4;
        return CGRectMake(x, y, w, h);
    }

    5)dismissTransitionWillBeginメソッドを書き換え、戻る遷移効果を設定する
    - (void)dismissalTransitionWillBegin
    - (void)dismissalTransitionWillBegin
    {
        id<UIViewControllerTransitionCoordinator> coordinator = self.presetingViewController.transitionCoordinator;
        [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonull context) {
            _shadowBtn.alpha = 0.01;
        } completion:nil];
    }

    6)dismissalTransitionDidEndメソッドを書き換え、クリーンアップ動作を実行する
    - (void)dismissalTransitionDidEnd:(BOOL)completed
    - (void)dismissalTransitionDidEnd:(BOOL)completed
    {
        if ( completed ) {
            [_shadowView removeFromSuperview];
        }
    }

         
  • 目的コントローラ設定遷移効果
  • ターゲットコントローラはプロキシプロトコルに従います
    @interface AMDestViewController () <UIViewControllerTransitioningDelegate>

    プロキシの設定
    self.transitioningDelegate = self;

    エージェントメソッドの実装
    - (UIPresetationController *) presentationControllerForPresentedViewController:(UIViewController*) presented presentingViewController:(UIViewController*) presenting sourceViewController:(UIViewController*) source
    {
        return [[AMPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
    }
  • ソースコントローラによるmodal切替
  • iOS8.0はこのようなカスタムの移行効果をサポートし始め、主に目的のコントローラのmodalPresentationStyleをカスタムに設定します.
    この切り替えは、iPhoneやiPadでも利用できます.
    AMDestViewController * vc = [[AMDestViewController alloct] init];
    vc.modalPresentationStyle = UIModalPresentationCustom;
    [self presentViewController:vc animated:YES completion:nil];