2017-03-28 1 views
0

J'ai un UIAlertController sans boutons (j'utilise cette alerte comme s'il vous plaît patienter pendant que certaines données charge le message) que je présente dans la fonction viewDidLoad de mon contrôleur de vue. Après je vous présente l'alerte que je lance une fonction qui récupère des informations à partir d'une base de données et une fois que cela est fait, je veux rejeter l'alerte afin que l'utilisateur peut procéder cependant l'alerte ne semble pas rejeter après l'exécution:Cant Dismiss UIAlertController à partir de la fonction séparée

self.dismiss(animated: true, completion: nil) 

I ont aussi essayé passer mon uialertcontroller comme argument à la fonction et l'exécution de la ligne suivante sans chance:

alertController.dismiss(animated: false, completion: nil) 

EDIT: Ceci est ma fonction viewDidLoad ainsi que la fonction qui devrait rejeter l'alerte

override func viewDidLoad() { 
    super.viewDidLoad() 

    let alertController = UIAlertController(title: "Loading", message: 
     "This might take a moment", preferredStyle: UIAlertControllerStyle.alert) 

    self.present(alertController, animated: true, completion: nil) 
    hideAlert(alert: alertController) 
} 

func hideAlert(alert: UIAlertController) { 
let hideAlertController = {() -> Void in 
alertController.dismiss(animated: false, completion: nil) 
} 
FIRDatabase.database().reference().child("info").observeSingleEvent(of: .value, with: { (dataSnapshot) in 
     DispatchQueue.main.async { 
      hideAlertController() 
     } 
    }) 
} 

Répondre

2

Essayez celui-ci dans votre ViewController:

var operationPerformed : Bool = false; 
override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning(); 
    // Dispose of any resources that can be recreated. 
} 

override func viewDidLoad() { 
    super.viewDidLoad(); 
} 
override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated); 
    if(!self.operationPerformed){ 
     let alertController = UIAlertController(title: "Loading", message: 
      "This might take a moment", preferredStyle: UIAlertControllerStyle.alert); 
     self.present(alertController, animated: true, completion: nil); 
     self.performOperation(alertToBeClosedOnFinish: alertController); 
    } 
} 

func performOperation(alertToBeClosedOnFinish: UIAlertController) { 
    let hideAlertController = {() -> Void in 
     alertToBeClosedOnFinish.dismiss(animated: false, completion: nil) 
    } 
    DispatchQueue.global().asyncAfter(deadline: .now() + 2, execute: { 
     DispatchQueue.main.async { 
      hideAlertController(); 
      self.operationPerformed = true; 
     } 
    }); 
} 

L'idée est de montrer contrôleur d'alerte quand il est propriétaire est dans la hiérarchie et si je vous comprends bien - vous voulez l'appeler une fois, vous devriez donc vérifier si l'opération a déjà été effectuée. Mais l'inconvénient d'une telle approche est d'essayer d'utiliser le contrôleur d'alerte lorsque vous pouvez créer votre vue d'avancement en tant que sous-classe de UIView et l'ajouter ou la retirer de/de superview. De plus, il y a beaucoup de gousses qui peuvent vous aider à y parvenir.

Cordialement, Sergey

0

La fonction qui extrait les informations de la base de données s'exécute-t-elle sur un thread différent? Si c'est le cas, vous ne pouvez pas mettre à jour l'interface utilisateur de ce thread. Les mises à jour de l'interface utilisateur ne peuvent avoir lieu que sur le thread principal. Que se passe-t-il lorsque vous enveloppez votre code avec ceci? :)

DispatchQueue.main.async { 
    alertController.dismiss(animated: false, completion: nil) 
} 
+1

Je viens de mise à jour le message original aussi comme je l'ai dit dans l'édition j'oublié de mentionner que j'essaie de rejeter l'alerte à l'intérieur d'une fermeture qui ne fonctionne sur un thread séparé mais après emballage l'appel de rejet dans l'async il n'a pas rejeté (j'ai également essayé d'enrouler l'appel à la fermeture avec l'async avec les mêmes résultats) – XvKnightvX

2

Permet d'afficher l'alerte dans les méthodes viewDidAppear(_:). Si ce n'est pas le cas, vous obtiendrez une erreur dont la vue ne figure pas dans la hiérarchie des fenêtres!:

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 

    let alertController = UIAlertController(title: "Loading", message: 
     "This might take a moment", preferredStyle: UIAlertControllerStyle.alert) 

    self.present(alertController, animated: true, completion: nil) 
} 

func hideAlert(alert: UIAlertController) { 

    let hide = {() -> Void in 
     alert.dismiss(animated: true, completion: nil) 
    } 

    let task = URLSession.shared.dataTask(with: URL(string: "https://www.google.com/")!) { (data, response, error) in 

     print("error: \(error)") 

     DispatchQueue.main.async { 
      hide() 
     } 
    } 
    task.resume() 
} 

Et ça marche!

enter image description here

+0

J'ai essayé de rejeter l'alerte dans viewDidAppear juste après la présentation cependant elle n'a pas été rejetée (désolé si J'ai mal compris ce que vous essayiez de suggérer) – XvKnightvX

+0

J'ai supposé charger des données d'une URL et cacher l'alerte quand c'est fait. Vous pouvez voir ma mise à jour! –

+0

Je suis en train de récupérer des données à partir d'une base de données Firebase en temps réel qui fonctionne sur un thread distinct du thread principal, mais appeler la fermeture à l'intérieur de DispatchQueue.main.async ne fonctionne pas pour moi. – XvKnightvX