2017-09-04 6 views
0

サブクラスUINavigationControllerを作成し、プッシュおよびポップトランジションを処理する非対話型のアニメーションオブジェクトを作成しました。これを完了するには、以下のカスタムポップアニメーションを処理するために​​を追加するにはどうすればよいですか?私はここからどこへ行くのか分かりにくいので、どんな助けもよかったですね、ありがとう!このポップアニメーションを処理するためにスクリーンエッジのパンジェスチャ認識機能を追加するにはどうすればよいですか?

class CustomNavigationController: UINavigationController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     delegate = self 
     isNavigationBarHidden = true 

    } 

} 

extension CustomNavigationController: UINavigationControllerDelegate { 

    // noninteractive animator objects 
    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { 

     switch operation { 

     case .push: 
      return CustomPushAnimator() 

     case .pop: 
      return CustomPopAnimator() 

     default: 
      return nil 

     } 

    } 

    // the interactive animator controller 
    func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 

     switch animationController { 

     case is CustomPopAnimator: 
      return CustomInteractiveController() 

     default: 
      return nil 

    } 

} 

// the noninteractive push animator 
class CustomPushAnimator: NSObject, UIViewControllerAnimatedTransitioning { 

    // push transition duration 
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 

     return 0.2 

    } 

    // push transition animation 
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 

     let viewWidth = UIScreen.main.bounds.width 
     let viewHeight = UIScreen.main.bounds.height 
     let containerView = transitionContext.containerView 
     let toViewController = transitionContext.viewController(forKey: .to) 

     containerView.addSubview((toViewController?.view)!) 
     toViewController?.view.frame = CGRect(x: viewWidth, y: 0, width: viewWidth, height: viewHeight) 

     UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: { 
      toViewController?.view.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight) 
     }, completion: { finished in 
      transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 
     }) 

    } 

} 

// the noninteractive pop animator 
class CustomPopAnimator: NSObject, UIViewControllerAnimatedTransitioning { 

    // pop transition duration 
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 

     return 0.2 

    } 

    // pop transition animation 
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 

     let viewWidth = UIScreen.main.bounds.width 
     let viewHeight = UIScreen.main.bounds.height 
     let containerView = transitionContext.containerView 
     let fromViewController = transitionContext.viewController(forKey: .from) 
     let toViewController = transitionContext.viewController(forKey: .to) 

     containerView.insertSubview((toViewController?.view)!, belowSubview: (fromViewController?.view)!) 

     UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: { 
      fromViewController?.view.frame = CGRect(x: viewWidth, y: 0, width: viewWidth, height: viewHeight) 
     }, completion: { finished in 
      fromViewController?.view.removeFromSuperview() 
      transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 
     }) 

    } 

} 

class CustomInteractiveController: NSObject, UIViewControllerInteractiveTransitioning { 

    func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) { 

     // I think the edge screen pan gesture goes here? Again, any advice is greatly appreciated! 

    } 

} 
+1

この質問を落とした人には、私は理由を感謝します。私はこのコードの研究と作成に多くの時間を費やし、非常に具体的な質問をしました。 – sconewolf

答えて

1

一般的には、インタラクティブなカスタムトランジションアニメーションを作成するための手順は次のとおりです。移行が始まる

  1. 前に、移行デリゲートを担当するビューコントローラを与えている必要があります。

  2. あなたには、対話的ジェスチャーを追跡するジェスチャー認識機能があります。ジェスチャ認識装置が認識すると、新しいビューコントローラへの遷移をトリガする。

  3. 移行が開始されると、デリゲートにアニメーションコントローラが要求されます。 UIViewControllerAnimatedTransitioningオブジェクトが返されます。

  4. 代理人には対話コントローラも尋ねられます。あなたは、UIViewControllerInteractiveTransitioningオブジェクト(または、対話からの移行を防ぐためにnil)を返します。このオブジェクトはstartInteractiveTransition(_:)を実装します。

  5. ジェスチャ認識機能は、遷移コンテキストで常にupdateInteractiveTransition(_:)を呼び出し、アニメーションのフレームを管理することによって継続します。

  6. 遅かれ早かれジェスチャーが終了します。この時点で、移行の完了またはキャンセルを宣言するかどうかを決定する必要があります。典型的なアプローチは、ユーザーが完全なジェスチャーの半分以上を実行した場合、それが完了を構成すると言います。そうでなければ、それはキャンセルを構成する。それに応じてアニメーションを完成させます。

  7. アニメーションが完了し、完了関数が呼び出されます。遷移コンテキストのfinishInteractiveTransitionまたはcancelInteractiveTransitionを呼び出してから、completeTransition(_:)を呼び出して、トランジションが完了したかキャンセルされたかを示す引数を付ける必要があります。

  8. 私たちのanimationEndedが呼び出され、クリーンアップされます。

    過去に

、あなたはあなたを助けるためにUIPercentDrivenInteractiveTransitionオブジェクトを使用することができますが、私はいつも、今日の私のカスタムトランジションアニメーションのためのUIViewPropertyAnimatorを使用します(iOSの10以降)。それを行うためにコード全体を書き直すことから始めなければならないでしょう。私は通常、UIViewPropertyAnimator、遷移コンテキスト(ジェスチャ認識器は参照が必要なため)、およびこれが対話型アニメーションかどうかを示すBoolフラグ(同じコードをインタラクティブで非対話型のものアニメーション)。

+0

私はあなたの助言を取り、 'UIViewPropertyAnimator'を使ってアニメーションをリファクタリングしました。私はGist https://gist.github.com/sconewolf/7a849fc691b63cf8721d6151831feae8を編集して作成しましたが、パンジェスチャ認識プログラムとハンドラを(下側の)インタラクティブコントローラにリンクする方法を理解することはできません。不足しているリンクは何ですか?私はこれまでに行ったことがありますが、0.999のハックのために嫌悪感を持っていますが、 'UIViewPropertyAnimator'を使ったチュートリアルは見つかりませんでした(明らかにiOS 10ではこれまで存在しなかったためです) )。 – sconewolf

+0

私が誰であるか知っていれば、あなたは私の本のコードがどこにあるのか知っています。私の答えで言ったことを示す本の例のコードを見つけることができます。 – matt

関連する問題