2015-08-24 6 views
15

я попробовать следующий фрагмент кода:Показать оповещения в AppDelegate в Swift

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! 

Как я могу исправить эту ошибку ?

+4

В 'AppDelegate', так описывает ошибку, иерархия окна еще не создан, поэтому оттуда вы можете нет ничего (в по крайней мере, из 'didFinishedLaunchingWithOptions'), поэтому вы должны переместить свой код в' ViewController' –

+0

@ DánielNagy, который я вижу, но я должен показать его из AppDelegate. Разве нет решений? –

+0

Возможный дубликат [чей вид не находится в иерархии окон] (http://stackoverflow.com/questions/11862883/whose-view-is-not-in-the-window-hierarchy) –

ответ

0

Я бы предложил НЕ делать это в AppDelegate. Делегат приложения предназначен для обработки функций делегата из ОС, а не для реализации таких вещей, как предупреждения.

Если вы хотите представить представление предупреждения, которое будет показано в начале приложения, я бы сделал это, выполнив его в вашем первом контроллере представления.

3

Я полагаю, вы вызываете этот фрагмент кода из приложенияDidFinishLunchingWithOptions:. Я попробовал это на самом деле, потому что должен был. Дело в том, что то, что вы пытаетесь сделать, является правильным, но ViewController, который AppDelegate делает и представляет, должен быть помещен на экран, и до этого фрагмент кода пытается создать 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 или другие части, тогда подумайте об этом.

В любом случае, надеюсь, что это поможет. Ура!

18

Это то, что я использую сейчас для этого.

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

СВИФТ 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) 
+0

Хотя этот ответ может решить проблему OP, было бы полезно выяснить, как это достигает решений. Простое сообщение только для кода может оказаться бесполезным для OP или будущих пользователей. Пожалуйста, дополните. –

+0

@GeoffJames сделано :) –

7

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

У вас пытался использовать UIApplication.shared.keyWindow?.rootViewController?.present(...)?

2

У меня была аналогичная проблема.

Я установил его, представив 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) 
} 
1

Согласно ответу Хорхе, обновленный для 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) 
Смежные вопросы