【问题标题】:Show alert in AppDelegate in Swift [duplicate]在 Swift 的 AppDelegate 中显示警报 [重复]
【发布时间】:2015-11-17 17:22:09
【问题描述】:

我试试下一个代码sn-p:

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!

我该如何解决这个错误?

【问题讨论】:

  • AppDelegate 中,如错误所述,尚未创建窗口层次结构,因此您无法从那里呈现任何内容(至少来自didFinishedLaunchingWithOptions),因此您应该移动代码到ViewController
  • @DánielNagy 我明白了,但我必须从 AppDelegate 展示它。没有解决办法吗?
  • @OrkhanAlizade 创建一个ViewController,将您的代码放入ViewControllers viewDidAppear 方法,并在您的AppDelegate 中,将ViewController 设置为窗口rootViewController(也不要'不要忘记创建窗口本身)。
  • @DánielNagy 它有效!谢谢!
  • @OrkhanAlizade 欢迎您!

标签: ios swift uialertcontroller


【解决方案1】:

我建议不要在 AppDelegate 中这样做。 App Delegate 它旨在处理来自操作系统的委托功能,而不是实现警报视图之类的东西。

如果您想在此处显示一个警报视图以在应用程序开始时显示,我会通过在您的第一个视图控制器中实现它来做到这一点。

【讨论】:

  • 如果您有多个更改的第一视图控制器怎么办?
【解决方案2】:

我想您是从 applicationDidFinishLunchingWithOptions: 调用该代码 sn-p 。事实上,我试过了,因为我不得不这样做。问题是:您尝试做的事情是正确的,但是 AppDelegate 制作和呈现的 ViewController 即将被放在屏幕上,在此之前,代码 sn-p 尝试创建一个 alertView 并放在不存在的顶部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 或其他部分会更好,那么你也要考虑一下。

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

【讨论】:

    【解决方案3】:

    这就是我现在用来做的。

    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)
    

    【讨论】:

      【解决方案4】:

      斯威夫特 5:

      let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertController.Style.alert)
              
      // add an action (button)
      alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
             
      // show the alert
      self.window?.rootViewController?.present(alert, animated: true, completion: nil)
      

      【讨论】:

      • 虽然这个答案可能会解决 OP 的问题,但值得详细说明它是如何实现解决方案的。简单地发布仅代码的答案可能对 OP 或未来的用户没有帮助。请详细说明。
      • @GeoffJames 完成 :)
      【解决方案5】:

      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)
      

      【讨论】:

      • in swift 4+ alertWindow.windowLevel = UIWindow.Level.alert+1
      • 最佳答案~~~~~
      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        我也遇到过类似的问题。

        我已通过在Main Queue 中显示UIAlertController 来修复它。

        代码如下所示。

        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)
        }
        

        【讨论】:

          【解决方案8】:

          根据 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)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-08-24
            • 2017-07-05
            • 2018-01-07
            • 2017-04-09
            • 2016-11-11
            • 2015-06-20
            相关资源
            最近更新 更多