2015-08-24 13 views
15

Ich versuche den nächsten Code-Schnipsel:anzeigen Alarm in AppDelegate in 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) 

in meinem AppDelegate, aber er druckt mir die nächsten Fehler in der Konsole:

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

Wie kann ich diesen Fehler zu beheben ?

+4

Im 'AppDelegate' für Swift aktualisiert, wie der Fehler beschreibt, wird das Fenster Hierarchie noch nicht erstellt, so von dort vorhanden man kann nichts (an Am wenigsten von der 'didFinishedLaunchingWithOptions'), so sollten Sie Ihren Code zu einem' ViewController' bewegen –

+0

@ DánielNagy ich sehe, aber ich muss es von AppDelegate zeigen. Gibt es keine Lösungen? –

+0

mögliches Duplikat von [dessen Ansicht nicht in der Fensterhierarchie ist] (http://stackoverflow.com/questions/11862883/whre-view-is-not-in-the-window-hierarchy) –

Antwort

0

Ich würde vorschlagen, dies nicht in der AppDelegate zu tun. Der App-Delegat wollte Delegate-Funktionen vom Betriebssystem aus handhaben, anstatt Dinge wie Warnmeldungen zu implementieren.

Wenn Sie hier eine Warnanzeige anzeigen möchten, die am Anfang der App angezeigt wird, würde ich dies tun, indem Sie sie in Ihrem ersten View-Controller implementieren.

3

Ich nehme an, dass Sie dieses Code-Snippet aus der applicationDidFinishLunchingWithOptions aufrufen:. Ich habe es ausprobiert, weil ich es musste. Die Sache ist: Was Sie zu tun versuchen, ist korrekt, aber der ViewController, den das AppDelegate erstellt und präsentiert, wird auf dem Bildschirm angezeigt und davor versucht das Code-Snippet, eine alertView zu erstellen und über die nicht existierende View of einzufügen der RootViewController.

Was ich tun würde, ist es zu einem anderen Delegat Anruf zu verschieben, die garantiert nach der RootViewController aufgerufen wird aufgerufen wird.

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) 

    } 

Aber wie immer die Verantwortung des AppDelegate. Es behandelt den Anwendungslebenszyklus und anwendungsweite Delegiertenaufrufe und -ereignisse. Wenn es sinnvoll ist, hier Code zu machen, dann mach es. Aber wenn Sie besser den Code auf den rootViewController oder andere Teile setzen, dann denken Sie darüber nach.

Wie auch immer, ich hoffe, es hilft. Prost!

18

Dies ist, was ich jetzt benutze, um das zu tun.

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

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) 
+0

Während diese Antwort das Problem des OP lösen könnte, wäre es sinnvoll, zu erläutern, wie dies zu den Lösungen führt. Das bloße Eingeben von Nur-Code-Antworten kann sich für das OP oder zukünftige Benutzer als wenig hilfreich erweisen. Bitte erläutern. –

+0

@GeoffJames erledigt :) –

7

Swift 3.0 oder höher, in allen Bedingungen arbeitet, wie im Fall der Tab-Leiste, bei vorgestellter Ansicht etc ..

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

Sie haben versucht mit UIApplication.shared.keyWindow?.rootViewController?.present(...)?

2

Ich hatte das ähnliche Problem.

Ich habe es durch Präsentieren UIAlertController in Main Queue behoben.

Code Sieht aus wie folgt.

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

Wie pro Antwort Jorge, 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) 
Verwandte Themen