2017-01-24 14 views
3

問題は、1つのトランジション・アニメーションのみで表示コントローラーを却下して表示する方法がわかりません。モーダル・ビュー・コントローラーを1つのアニメーションで消して表示する

マイストーリーボードの構造は次のとおりです。

enter image description here 我々はコントローラがNavigationControllerを以下のものです、Bスタートアップ参照であり、CがTabBarのViewControllerをであると言うことができます。 Bおよびの両方が、クロスディゾルブの遷移を伴って提示される。

場合、ユーザログイン(Bから)アプリには、Cコントローラはフリップ水平遷移にモーダル提示されます。ユーザーがログアウトすると(C)、Bが同様に表示されます。 オンコントローラ私はBまたはCにユーザーがログに記録されているかどうかによって直接セグを実行します。

私の問題は、私はBまたはCから前のビューコントローラを却下していない場合は、そのコントローラが漏洩していることです。反対に、それを却下すると、ターゲットコントローラ(BまたはC)の前に、Aが表示されます。

フリップ水平のトランジションとステップオーバーを表示することはできますか?Aビュー?

答えて

2

、この問題への私のソリューションは、さまざまなアニメーションをサポートし、現在のrootViewControllerを交換したのソルバー

この遅れ答えを
static func replaceRootViewController(with:UIViewController, transition:UIViewAnimationOptions, completion:(() ->())? = nil) {   
    if transition == .transitionCrossDissolve { 
     let overlayView = UIScreen.main.snapshotView(afterScreenUpdates: false) 
     with.view.addSubview(overlayView) 
     UIApplication.shared.keyWindow?.rootViewController = with 

     UIView.animate(withDuration: 0.65, delay: 0, options: transition, animations: { 
      overlayView.alpha = 0 
     }, completion: { finished in 
      overlayView.removeFromSuperview() 
      if let completion = completion{ 
       completion() 
      } 
     }) 
    } else { 
     _ = with.view 
     UIView.transition(with: UIApplication.shared.keyWindow!, duration: 0.65,options: transition, animations: { 
      UIApplication.shared.keyWindow?.rootViewController = with 
     }){_ in 
      if let completion = completion { 
       completion() 
      } 

     } 
    } 
} 
1

これは私がこの問題に使用した解決策です。私はストーリーボードを使っていないので、ストーリーボードとどのように統合されているのか分かりません。

このメソッドをUIViewControllerにカテゴリとして追加し、以前にpresentViewController:animated:completionと呼ばれていた場所のいずれかを呼び出すことができます。新しいコントローラの継ぎ目のないアニメーションを作成しながら、以前のものを削除します。

-(void)presentViewControllerDismissingPrevious:(UIViewController* _Nonnull)controller animated:(BOOL)animated completion:(void (^ __nullable)(void))completion { 

    UIViewController* visibleController = self; 
    { 
     UIViewController* temp; 
     while((temp = visibleController.presentedViewController) != nil) { 
      visibleController = temp; 
     } 
    } 

    if(visibleController == self) { 
     // no previous controller to dismiss 
     [self presentViewController:controller animated:animated completion:completion]; 
    } else { 
     // create a temporary snapshot of the visible controller's entire window 
     // and add to the current view controller's window until animation completed 
     UIWindow* visibleWindow = visibleController.view.window; 
     UIView* tempView = [visibleWindow snapshotViewAfterScreenUpdates:NO]; 
     UIView* rootView = self.view.window.subviews[0]; 
     tempView.frame = [rootView convertRect:visibleWindow.bounds fromView:visibleWindow]; 
     [rootView addSubview:tempView]; 

     [self dismissViewControllerAnimated:NO completion:^(){ 
      [self presentViewController:controller animated:animated completion:^(){ 
       [tempView removeFromSuperview]; 
       if(completion) { 
        completion(); 
       } 
      }]; 
     }]; 
    } 
} 
+0

申し訳ありませんが、この記事のいくつかの日後に私が見つけたそれをする方法を私がするのを忘れましたここにそれを公開してください。 私のしたことは、あなたのソリューションに非常によく似ていますが、もっと完全です(フリップアニメーションもサポートしています)。 – kikettas

関連する問題