0

在一段時間後,我得到這樣的錯誤:如何防止嘗試在已經呈現的控制器上顯示控制器的錯誤?

Warning: Attempt to present <Controller3> on <Controller1> which is already presenting <Controller2> 

我明白,一個控制器需要被這就是在堆棧的頂部(控制器2),而不是一個控制器某處下面的控制器上呈現(控制器1 )。

不是一次性修復這些錯誤,我們如何設計我們的應用程序來一勞永逸地防止這個問題?

回答

0

這個問題的一個乾淨的解決方案是導航控制器。

如果您不能或不想使用一個,你可以很容易地模擬它一個普通視圖控制器:

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() ,類似於導航控制器。此外,您可以在堆棧中的任何控制器上調用這些方法,並且它會自動將它們重定向到最上面的控制器,從而防止問題中出現錯誤。

此擴展還解決了如果您想關閉控制器並呈現另一個控制器,則只需要在完成塊中顯示即使沒有動畫也沒有關閉的問題。否則,您將得到與上述相同的錯誤。此擴展可修復所有這些問題。

相關問題