この問題の解決策の1つはナビゲーションコントローラです。
あなたがまたは1つを使用したくないことができない場合は、簡単に通常のビューコントローラ上でそれをシミュレートすることができます。
extension UIViewController {
var topViewController: UIViewController {
return presentedViewController == nil ? self : presentedViewController!.topViewController
}
// If the topmost view controller is an instance of one of the given classes, it's popped.
// Then, the given view controller, if any, if pushed.
//
// This function can be called on any of the view controllers in the stack.
func pop(ifOneOf: [AnyClass], thenPush: UIViewController? = nil) {
if topViewController.presentingViewController != nil && topViewController.isKindOfOneOf(ifOneOf) {
topViewController.dismiss(animated: false, completion: {
self.pop(ifOneOf: [], thenPush: thenPush)
})
return
}
if thenPush != nil {
push(thenPush!)
}
}
// Pushes the given view controller onto the stack.
//
// This method can be called on any of the view controllers in the stack.
func push(_ child: UIViewController) {
topViewController.present(child, animated: true)
}
}
extension NSObjectProtocol {
func isKindOfOneOf(_ classes: [AnyClass]) -> Bool {
for clazz in classes {
if isKind(of: clazz) {
return true
}
}
return false
}
}
あなたが見ることができるように、これはプッシュ()とポップを提供します()ナビゲーションコントローラに似ています。さらに、スタック内のどのコントローラでもこれらのメソッドを呼び出すことができます。これらのメソッドは、最上位のコントローラに自動的にリダイレクトされ、質問のエラーを防ぎます。
この拡張機能では、コントローラを無効にして別のものを提示したい場合、アニメーションなしで終了しても完了ブロックにのみ表示する必要があるという問題も修正されています。それ以外の場合は、上記と同じエラーが発生します。この拡張機能は、これらの問題をすべて修正します。