【问题标题】:Present UIAlertController from AppDelegate [duplicate]从 AppDelegate 呈现 UIAlertController [重复]
【发布时间】:2015-01-13 03:31:59
【问题描述】:

我正在尝试在我的 iOS 应用程序中从 AppDelegate 提供UIAlertController。 下面是警报和当前方法。

UIAlertController *alert = [UIAlertController alertControllerWithTitle:cTitle message:cMessage preferredStyle:UIAlertControllerStyleAlert];

//Configure alert and actions

[self.window.rootViewController presentViewController:alert animated:TRUE completion:nil];

但是,当我尝试显示警报时,它没有出现,并且我在控制台中收到以下警报。

Warning: Attempt to present <UIAlertController: 0x145f5d60> on <UINavigationController: 0x146590f0> whose view is not in the window hierarchy!

是什么导致了错误,我该如何解决?

【问题讨论】:

标签: ios objective-c appdelegate uialertcontroller


【解决方案1】:

如果您想从 didFinishLaunchingWithOptions 启动它,也可以使用此代码。希望这会有所帮助。

dispatch_async(dispatch_get_main_queue(), {
              let importantAlert: UIAlertController = UIAlertController(title: "Action Sheet", message: "Hello I was presented from appdelegate ;)", preferredStyle: .ActionSheet)
            self.window?.rootViewController?.presentViewController(importantAlert, animated: true, completion: nil)
        })

并且是最新的:

DispatchQueue.main.async {
    let alert = UIAlertController(title: "Hello!", message: "Greetings from AppDelegate.", preferredStyle: .alert)
    self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}

【讨论】:

  • 嗨@AdiQuadCore,你的只有在快速应用程序中才有用。在 objC 中,UIAlertController 需要一个指向当前 UIViewController 的指针。
  • 这在 didFinishLaunchingWithOptions 中的 ObjC 中对我有用
【解决方案2】:

试试这个代码..

-(void)application:(UIApplication *)application               didReceiveLocalNotification:(UILocalNotification *)notification
{
 NSLog(@"rakshapettu");
 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"AlertView" message:@"I am an AlertView" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction * action) {
                                                          [alert dismissViewControllerAnimated:YES completion:nil];
                                                      }];
[alert addAction:defaultAction];
UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
alertWindow.rootViewController = [[UIViewController alloc] init];
alertWindow.windowLevel = UIWindowLevelAlert + 1;
[alertWindow makeKeyAndVisible];
[alertWindow.rootViewController presentViewController:alert animated:YES completion:nil]; 
}

【讨论】:

  • UIWindow 是如何释放的?
【解决方案3】:

最好使用类似的东西:

var hostVC = self.window?.rootViewController

while let next = hostVC?.presentedViewController {
    hostVC = next
}

hostVC?.presentViewController(alertController, animated: true, completion: nil)

如果您已经在展示模态视图控制器,则以前的答案将不起作用。

【讨论】:

  • 完美的答案和一个非常好的方法来处理模态呈现的视图控制器!谢谢!
【解决方案4】:

你在窗口打开之前调用它,navigationController 实际显示出来:

“警告:试图展示不在窗口层次结构中的视图!”

您可能会在 applicationDidFinishLaunching 中这样做吗?


等一下 .. 喜欢在视图真正出现时这样做

一个“黑客”是强制视图和窗口自己打开:

[self.window addSubview:self.rootViewController.view];
[self.window makeKeyAndVisible];

【讨论】:

  • 如果你没有创建一个新的Window,你还需要makeKeyAndVisible吗? AppDelegate自带的window,是不是默认会这样?!
  • 一般来说:是的,但是对于操作员的问题来说太晚了
  • 我很困惑。你是什​​么意思太晚了?你的代码是否正确?
  • 我对给定的问题是正确的 :) 这里需要 makeKeyAndVisible
【解决方案5】:

我尝试了同样的方法,但不起作用,因为在更改视图控制器后仍然返回初始视图控制器并抛出错误 whose view is not in the window hierarchy!。终于找到了解决这个问题的办法:

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

但我必须强制视图控制器更新 de keyWindow

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    UIApplication.sharedApplication().keyWindow!.rootViewController = self
    UIApplication.sharedApplication().keyWindow!.makeKeyAndVisible()
}

【讨论】:

  • 你不应该那样做,真的。
【解决方案6】:

您可以尝试使用viewDidAppear 而不是viewDidLoad 调用它。我有一个类似的错误并修复了它。

【讨论】:

    【解决方案7】:

    使用警报控制器:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    dispatch_async(dispatch_get_main_queue(), {
    
        //INTERNET NOT AVAILABLE ALERT
        var internetUnavailableAlertController = UIAlertController (title: "Network Unavailable", message: "Please check your internet connection settings and turn on Network Connection", preferredStyle: .Alert)
    
        var settingsAction = UIAlertAction(title: "Settings", style: .Default) { (_) -> Void in
            let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
            if let url = settingsUrl {
                UIApplication.sharedApplication().openURL(url)
            }
        }
        var cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil)
        internetUnavailableAlertController .addAction(settingsAction)
        internetUnavailableAlertController .addAction(cancelAction)
        self.window?.rootViewController!.presentViewController(internetUnavailableAlertController , animated: true, completion: nil)
        })
    

    使用警报视图:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
        dispatch_async(dispatch_get_main_queue(), {
    
            //INTERNET NOT AVAILABLE ALERTVIEW
    
            let internetUnavailableAlert =  UIAlertView(title: "Network Unavailable", message: "Please check your internet connection settings and turn on Network Connection", delegate: self, cancelButtonTitle: "Okay")
            internetUnavailableAlert.show()
            })
    
      return true
     }
    }
    

    【讨论】:

    • UIAlertView 现已弃用。
    猜你喜欢
    • 1970-01-01
    • 2021-08-17
    • 2020-08-25
    • 2015-08-09
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 2016-01-09
    • 1970-01-01
    相关资源
    最近更新 更多