2015-08-24 11 views
15

cerco il codice successivo frammento di:Visualizza avviso in AppDelegate a 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) 

nel mio AppDelegate, ma mi stampa il successivo errore in console:

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

Come posso risolvere questo errore ?

+4

Nel 'AppDelegate', come l'errore descrive, la gerarchia finestra non è ancora creata, quindi da lì si può non presente nulla (a almeno dal 'didFinishedLaunchingWithOptions'), quindi dovresti spostare il tuo codice su' ViewController' –

+0

@ DánielNagy vedo, ma devo mostrarlo da AppDelegate. Non ci sono soluzioni? –

+0

possibile duplicato di [la cui vista non è nella gerarchia della finestra] (http://stackoverflow.com/questions/11862883/whose-view-is-not-in-the-window-hierarchy) –

risposta

0

Suggerirei di NON farlo in AppDelegate. Il delegato dell'app intendeva gestire le funzioni di delegazione dal sistema operativo anziché implementare elementi come le viste di avviso.

Se si desidera presentare una vista di avviso qui per essere mostrata all'inizio dell'applicazione, lo farei implementandola nel primo controller della vista.

3

Suppongo che tu stia chiamando quel frammento di codice da applicationDidFinishLunchingWithOptions:. L'ho provato come dato di fatto perché dovevo. La cosa è: quello che stai cercando di fare è corretto, ma il ViewController che AppDelegate fa e presenta sta per essere messo sullo schermo e prima di questo, il frammento di codice prova a creare un alertView e inserirlo in una vista non esistente di il RootViewController.

Quello che vorrei fare è spostarlo su un'altra chiamata delegata che è garantita per essere chiamata dopo la presentazione del 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) 

    } 

Ma come sempre, conoscere la responsabilità dell'AppDelegate. È gestire il ciclo di vita dell'applicazione e le chiamate ed eventi delegati a livello di applicazione. Se mettere il codice qui ha senso, allora fallo. Ma se farai meglio a inserire il codice sul rootViewController o su altre parti, pensaci anche tu.

In ogni caso, spero che sia d'aiuto. Saluti!

18

Questo è quello che sto usando ora per farlo.

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

Mentre questa risposta può risolvere il problema dell'OP, varrebbe la pena di approfondire come questo raggiunge le soluzioni. La semplice pubblicazione di risposte solo in codice potrebbe rivelarsi inutile per l'OP o per i futuri utenti. Si prega di elaborare. –

+0

@GeoffJames completati :) –

7

Swift 3.0 o superiore, Lavorare in tutte le condizioni, come nel caso di barra delle schede, in caso di vista presentato ecc ..

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

Avete provato a usare UIApplication.shared.keyWindow?.rootViewController?.present(...)?

2

Ho avuto il problema simile.

L'ho risolto presentando UIAlertController in Main Queue.

Codice Sembra essere il seguente.

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

Come per la risposta di Jorge, aggiornato per 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) 
Problemi correlati