2015-05-05 11 views
10

Ho problemi a visualizzare il mio UIAlertController perché sto provando a visualizzarlo in una classe che non è un ViewController.mostra UIAlertController all'esterno di ViewController

ho già provato ad aggiungere che:

var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert) 

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

che non funziona ... non ho trovato alcuna soluzione che ha funzionato per me ancora.

+0

La classe che non è un UIViewController ora è in parte non verificabile. Prendere in considerazione l'aggiunta di un delegato o di una richiamata basata su blocchi per visualizzare l'avviso sul controller della vista che sta utilizzando questa classe. – 3lvis

risposta

27

Ho scritto questo extension sopra UIAlertController per riportare show().
Esso utilizza la ricorsione per trovare l'attuale top vista del regolatore:

extension UIAlertController { 

    func show() { 
     present(animated: true, completion: nil) 
    } 

    func present(#animated: Bool, completion: (() -> Void)?) { 
     if let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController { 
      presentFromController(rootVC, animated: animated, completion: completion) 
     } 
    } 

    private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) { 
     if let navVC = controller as? UINavigationController, 
      let visibleVC = navVC.visibleViewController { 
       presentFromController(visibleVC, animated: animated, completion: completion) 
     } else 
     if let tabVC = controller as? UITabBarController, 
      let selectedVC = tabVC.selectedViewController { 
       presentFromController(selectedVC, animated: animated, completion: completion) 
     } else { 
      controller.presentViewController(self, animated: animated, completion: completion); 
     } 
    } 
} 

Ora è facile come:

var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert) 
alertController.show() 

EDIT:

Per Xcode 8.0 & Swift 3:

extension UIAlertController { 

    func show() { 
     present(animated: true, completion: nil) 
    } 

    func present(animated: Bool, completion: (() -> Void)?) { 
     if let rootVC = UIApplication.shared.keyWindow?.rootViewController { 
      presentFromController(controller: rootVC, animated: animated, completion: completion) 
     } 
    } 

    private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) { 
     if let navVC = controller as? UINavigationController, 
      let visibleVC = navVC.visibleViewController { 
      presentFromController(controller: visibleVC, animated: animated, completion: completion) 
     } else 
      if let tabVC = controller as? UITabBarController, 
       let selectedVC = tabVC.selectedViewController { 
       presentFromController(controller: selectedVC, animated: animated, completion: completion) 
      } else { 
       controller.present(self, animated: animated, completion: completion); 
     } 
    } 
} 
+0

È grandioso! Grazie mille – Michael

+0

Contento che funzioni per voi, lo sto usando con molti scenari VC (modale vc su una pila di nav all'interno di un controller della barra delle linguette ecc.), Fatemi sapere se c'è una situazione in cui ciò non funziona. .. –

+0

SharedApplication non può essere utilizzato in un'estensione per app. – SAHM

0

Creare una funzione di supporto che si chiama dal controller vista corrente e passare il controller di vista corrente come parametro:

func showAlertInVC(
    viewController: UIViewController, 
    title: String, 
message: String) 
{ 
    //Code to create an alert controller and display it in viewController 
} 
0

Se la soluzione non funziona, probabilmente a causa della non c'è nessuna finestra in quel momento . Ho avuto lo stesso problema quando stavo cercando di mostrare la vista di avviso nel metodo application:DidFinishLoadingWithOptions. In questo caso la mia soluzione era quella di verificare se vista radice controller è disponibile, e se non lo è, quindi aggiungere la notifica per UIApplicationDidBecomeActiveNotification

NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationDidBecomeActiveNotification, 
       object: nil, 
       queue: NSOperationQueue.mainQueue()) { 
        (_) in 
         //show your alert by using root view controller 
         //remove self from observing 
        } 
     } 
0

Questo dovrebbe funzionare.

UIApplication.sharedApplication().windows[0].rootViewController?.presentViewController(...)