在Swift中的AppDelegate中显示警报

时间:2015-08-24 10:10:55

标签: ios swift uialertcontroller

我尝试下一个代码段:

var alert = UIAlertController(title: "Alert", message: "Cannot connect to : \(error!.localizedDescription)", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)

在我的AppDelegate中,但它在控制台中打印出下一个错误:

Warning: Attempt to present <UIAlertController: 0x7ff6cd827a30> on <Messenger.WelcomeController: 0x7ff6cb51c940> whose view is not in the window hierarchy!

如何解决此错误?

8 个答案:

答案 0 :(得分:29)

这就是我现在用来做的事情。

var alertController = UIAlertController(title: "Title", message: "Any message", preferredStyle: .ActionSheet)
var okAction = UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default) {
                    UIAlertAction in
                    NSLog("OK Pressed")
                }
var cancelAction = UIAlertAction(title: "No", style: UIAlertActionStyle.Cancel) {
                    UIAlertAction in
                    NSLog("Cancel Pressed")
                }
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.window?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)

答案 1 :(得分:15)

SWIFT 3

let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertControllerStyle.alert)

// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))

// show the alert
self.window?.rootViewController?.present(alert, animated: true, completion: nil)

答案 2 :(得分:13)

Swift 3.0或以上版本,适用于所有条件,例如标签栏,以及呈现视图等。

let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertControllerStyle.alert)

// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))

// show alert
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert + 1;
alertWindow.makeKeyAndVisible()
alertWindow.rootViewController?.present(alertController, animated: true, completion: nil)

答案 3 :(得分:9)

根据Jorge的回答,更新了Swift 4

let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
        UIAlertAction in
        NSLog("OK Pressed")
    }
let cancelAction = UIAlertAction(title: "CANCEL", style: UIAlertActionStyle.cancel) {
        UIAlertAction in
        NSLog("Cancel Pressed")
    }
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.window?.rootViewController?.present(alertController, animated: true, completion: nil)

答案 4 :(得分:7)

我遇到了类似的问题。

我已通过在UIAlertController中展示Main Queue来解决此问题。

代码如下所示。

let alert = UIAlertController(title: "My Title", message: "My Message", preferredStyle: .alert)

let actionYes = UIAlertAction(title: "Yes", style: .default, handler: { action in
print("action yes handler")
})

let actionCancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { action in
print("action cancel handler")
})

alert.addAction(actionYes)
alert.addAction(actionCancel)

DispatchQueue.main.async {
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}

答案 5 :(得分:3)

我想你是从applicationDidFinishLunchingWithOptions调用那段代码片段:。事实上我试过了,因为我不得不这样做。问题是:你要做的是正确的,但AppDelegate制作和呈现的ViewController即将被放到屏幕上,在此之前,代码片段尝试创建一个alertView并放在不存在的View of Top之上RootViewController。

我要做的是将它移动到另一个委托调用,保证在RootViewController出现后调用。

    func applicationDidBecomeActive(application: UIApplication) {
     //This method is called when the rootViewController is set and the view.
     // And the View controller is ready to get touches or events.
    var alert = UIAlertController(title: "Alert", message: "Cannot connect to :", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
    self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)

    }

但是一如既往地了解AppDelegate的责任。它是处理应用程序生命周期和应用程序范围的委托调用和事件。如果把代码放在这里是有道理的,那就去做吧。但是如果您最好将代码放在rootViewController或其他部分上,那么也要考虑它。

无论如何,希望它有所帮助。干杯!

答案 6 :(得分:3)

您是否尝试过使用UIApplication.shared.keyWindow?.rootViewController?.present(...)

答案 7 :(得分:0)

我建议不要在AppDelegate中这样做。 App Delegate旨在从操作系统处理委托功能,而不是实现警报视图等。

如果您想要在此处显示警报视图以在应用程序的开头显示,我将通过在您的第一个视图控制器中实现它来执行此操作。