這個問題的一個乾淨的解決方案是導航控制器。
如果您不能或不想使用一個,你可以很容易地模擬它一個普通視圖控制器:
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
}
}
正如你所看到的,這提供了推()和pop() ,類似於導航控制器。此外,您可以在堆棧中的任何控制器上調用這些方法,並且它會自動將它們重定向到最上面的控制器,從而防止問題中出現錯誤。
此擴展還解決了如果您想關閉控制器並呈現另一個控制器,則只需要在完成塊中顯示即使沒有動畫也沒有關閉的問題。否則,您將得到與上述相同的錯誤。此擴展可修復所有這些問題。