5

いくつかのカスタム モーダル プレゼンテーションとカスタム コントローラー (UIViewController のサブクラス) を提示します。これは独自の移行デリゲートであり、アニメーション化された移行オブジェクトとプレゼンテーション コントローラーを返します。アニメーション化されたトランジション オブジェクトを使用して、表示時に表示されたビューをコンテナー ビューに追加し、閉じるときにそれを削除し、もちろんアニメーション化します。プレゼンテーション コントローラーを使用してヘルパー サブビューを追加します。

public final class PopoverPresentationController: UIPresentationController {
    private let touchForwardingView = TouchForwardingView()

    override public func presentationTransitionWillBegin() {
        super.presentationTransitionWillBegin()
        self.containerView?.insertSubview(touchForwardingView, atIndex: 0)
    }
}

public final class PopoverAnimatedTransitioning: NSObject, UIViewControllerAnimatedTransitioning {

    func setupView(containerView: UIView, presentedView: UIView) {
        //adds presented view to container view 
    }

    public func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        //1. setup views 
        //2. animate presentation or dismissal
    }
}

public class PopoverViewController: UIViewController, UIViewControllerTransitioningDelegate {

    init(...) {
        ...
        modalPresentationStyle = .Custom
        transitioningDelegate = self
    }

    public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return PopoverAnimatedTransitioning(forPresenting: true, position: position, fromView: fromView)
    }

    public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return PopoverAnimatedTransitioning(forPresenting: false, position: position, fromView: fromView)
    }

    public func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController?, sourceViewController source: UIViewController) -> UIPresentationController? {
        return PopoverPresentationController(presentedViewController: presented, presentingViewController: presenting, position: position, fromView: fromView)
    }

}

presentViewControllerコントローラーを提示し、プロパティに true を渡すと、すべて正常に動作しanimatedます。しかし、アニメーションなしで表示したいときに false を渡すと、UIKit はpresentationControllerForPresentedViewControllerメソッドを呼び出すだけで、まったく呼び出しませんanimationControllerForPresentedController。そして、提示されたビューがビュー階層に追加され、作成されないアニメーション遷移オブジェクトに配置される限り、何も提示されません。

私がやっていることは、トランジションがアニメーション化されているかどうかをプレゼンテーションコントローラーでチェックしていることです。アニメーション化されていない場合は、アニメーション化されたトランジションオブジェクトを手動で作成し、ビューをセットアップします。

override public func presentationTransitionWillBegin() {
    ...
    if let transitionCoordinator = presentedViewController.transitionCoordinator() where !transitionCoordinator.isAnimated() {
        let transition = PopoverAnimatedTransitioning(forPresenting: true, position: position, fromView: fromView)
        transition.setupView(containerView!, presentedView: presentedView()!)
    }
}

それは機能しますが、それが最善のアプローチであるかどうかはわかりません。

ドキュメンテーションによると、プレゼンテーション コントローラーは遷移中の追加のセットアップまたはアニメーションの実行のみを担当し、プレゼンテーションの主な作業はアニメーション化された遷移オブジェクトで行う必要があります。

ビューを常にプレゼンテーション コントローラーに設定し、アニメーション化されたトランジション オブジェクトでのみアニメーション化しても問題ありませんか?

その問題を解決するためのより良い方法はありますか?

4

1 に答える 1