0

ナビゲーション コントローラーをポップまたはプッシュするときに、カスタム トランジションを作成しようとしています。UINavigationControllerDelegate に準拠する transitionManager クラスを作成しました。この transitionManager のオブジェクトを作成し、それを transitioningDelegate として navigationController に追加しました。

プッシュ アニメーションはうまく動作しますが、前の viewController に戻ろうとすると、黒い画面しか表示されません。

私はそれを機能させるために他の多くの投稿を実行し、手元にあるすべてを試しましたが、ポップしても以前の ViewController が表示されません。

transitionManager のコードは次のとおりです。

import UIKit

class BRTransitionManager: NSObject, UINavigationControllerDelegate, UIViewControllerAnimatedTransitioning {

    private var presenting = true

    func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        if  operation == UINavigationControllerOperation.Push{
            self.presenting = true
        } else if operation == UINavigationControllerOperation.Pop{
            self.presenting = false
        }

        return self
    }

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        let container = transitionContext.containerView()
        let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
        let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!

        // set up from 2D transforms that we'll use in the animation
        let offScreenRight = CGAffineTransformMakeTranslation(container.frame.width, 0)
        let offScreenLeft = CGAffineTransformMakeTranslation(-container.frame.width, 0)

        // prepare the toView for the animation
        if (self.presenting == true) {
            // add the both views to our view controller
            container.addSubview(toView)
            // container.addSubview(fromView)

            toView.transform = offScreenRight
        } else {
            toView.transform = offScreenLeft
        }

        let duration = self.transitionDuration(transitionContext)
        UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: nil, animations: {

            if (self.presenting == true) {
                fromView.transform = offScreenLeft
            } else {
                fromView.transform = offScreenRight
            }

            toView.transform = CGAffineTransformIdentity

        }, completion: { finished in

            transitionContext.completeTransition(true)
        })
    }

    func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
        return 0.8
    }   
}
4

1 に答える 1

1

UINavigationController は、そのデリゲートへの弱い参照を維持します。強い参照がない場合、遷移が完了すると UINavigationControllerDelegate オブジェクトの割り当てが解除されます。

ストーリーボード エディターでデリゲート オブジェクトを設定できます。オブジェクトをパレットからナビゲーション コントローラー シーンの First Responder アイコンと Exit アイコンの間にドラッグして、オブジェクトを追加します。そのクラスをデリゲート オブジェクトのクラスに設定します。モジュールが現在のアプリケーション モジュールであることを確認します。次に、Navigation Controller アイコンからオブジェクト アイコンにコントロールを押しながらドラッグし、ポップアップ メニューから [委任] を選択します。

これはデリゲート オブジェクトへの強い参照を維持しているようです。その後、デリゲート オブジェクトを使用してアンワインド トランジションを呼び出すことができます。自分でオブジェクトを作成したり、デリゲート参照を設定したりする必要はありません。

この手法は、Scott James Remnant によるブログ投稿で見つけました。

Scott James Remnant - iOS のカスタム セグエ、トランジション、およびアニメーション - 正しい方法

于 2016-01-08T19:06:38.277 に答える