いくつかのカスタム モーダル プレゼンテーションとカスタム コントローラー (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()!)
}
}
それは機能しますが、それが最善のアプローチであるかどうかはわかりません。
ドキュメンテーションによると、プレゼンテーション コントローラーは遷移中の追加のセットアップまたはアニメーションの実行のみを担当し、プレゼンテーションの主な作業はアニメーション化された遷移オブジェクトで行う必要があります。
ビューを常にプレゼンテーション コントローラーに設定し、アニメーション化されたトランジション オブジェクトでのみアニメーション化しても問題ありませんか?
その問題を解決するためのより良い方法はありますか?