2015-05-05 126 views
10

我無法顯示我的UIAlertController,因爲我試圖在不是ViewController的類中顯示它。在ViewController之外顯示UIAlertController

我已經嘗試添加它:

var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert) 

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil) 

這是不工作... 我沒有找到適合我的工作還沒有任何解決方案。

+0

你是不是UIViewController的類現在部分無法測試。考慮添加一個委託或基於塊的回調以在使用此類的視圖控制器上顯示警報。 – 3lvis

回答

27

我寫這extensionUIAlertController帶回show()
它使用遞歸來查找當前頂視圖控制器:

extension UIAlertController { 

    func show() { 
     present(animated: true, completion: nil) 
    } 

    func present(#animated: Bool, completion: (() -> Void)?) { 
     if let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController { 
      presentFromController(rootVC, animated: animated, completion: completion) 
     } 
    } 

    private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) { 
     if let navVC = controller as? UINavigationController, 
      let visibleVC = navVC.visibleViewController { 
       presentFromController(visibleVC, animated: animated, completion: completion) 
     } else 
     if let tabVC = controller as? UITabBarController, 
      let selectedVC = tabVC.selectedViewController { 
       presentFromController(selectedVC, animated: animated, completion: completion) 
     } else { 
      controller.presentViewController(self, animated: animated, completion: completion); 
     } 
    } 
} 

現在是那麼容易,因爲:

var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert) 
alertController.show() 

編輯:

有關的Xcode 8.0 &斯威夫特3:

extension UIAlertController { 

    func show() { 
     present(animated: true, completion: nil) 
    } 

    func present(animated: Bool, completion: (() -> Void)?) { 
     if let rootVC = UIApplication.shared.keyWindow?.rootViewController { 
      presentFromController(controller: rootVC, animated: animated, completion: completion) 
     } 
    } 

    private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) { 
     if let navVC = controller as? UINavigationController, 
      let visibleVC = navVC.visibleViewController { 
      presentFromController(controller: visibleVC, animated: animated, completion: completion) 
     } else 
      if let tabVC = controller as? UITabBarController, 
       let selectedVC = tabVC.selectedViewController { 
       presentFromController(controller: selectedVC, animated: animated, completion: completion) 
      } else { 
       controller.present(self, animated: animated, completion: completion); 
     } 
    } 
} 
+0

太棒了!非常感謝 – Michael

+0

很高興它爲你工作,我一直在很多VC場景(在標籤欄控制器內的導航堆棧上的modal vc等)使用它,請讓我知道如果這種情況不起作用。 .. –

+0

SharedApplication不能在應用程序擴展中使用。 – SAHM

0

創建從當前視圖控制器調用輔助功能,並通過當前視圖控制器作爲參數:

func showAlertInVC(
    viewController: UIViewController, 
    title: String, 
message: String) 
{ 
    //Code to create an alert controller and display it in viewController 
} 
0

如果解決方案是不大概的工作,因爲那裏是在那一刻沒有窗口。當我試圖在application:DidFinishLoadingWithOptions方法中顯示警報視圖時,我遇到了同樣的問題。在這種情況下我的解決辦法是,以檢查是否根視圖控制器是可用的,如果不是的話,再加入通知UIApplicationDidBecomeActiveNotification

NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationDidBecomeActiveNotification, 
       object: nil, 
       queue: NSOperationQueue.mainQueue()) { 
        (_) in 
         //show your alert by using root view controller 
         //remove self from observing 
        } 
     } 
0

這應該工作。

UIApplication.sharedApplication().windows[0].rootViewController?.presentViewController(...)