2017-02-25 3 views
1

J'ai un problème avec la fonction sleep en code Swift. J'utilise import Darwin et usleep(400000). Certaines actions avant d'atteindre le sommeil sont bloquées et je ne sais pas pourquoi. Voici un court exemple de mon code:retard/sommeil dans Swift ne fonctionne pas

@IBAction func Antwort4Button(_ sender: Any) { 
    if (richtigeAntwort == "4"){ 
     Antwort4.backgroundColor = UIColor.green 
     Ende.text = "Richtig!" 

     NaechsteFrage() 
    } 
    else { 
     Ende.text = "Falsch!" 

     //NaechsteFrage() 
    } 
} 

func NaechsteFrage() { 
    usleep(400000) 

    Antwort1.backgroundColor = UIColor.red 
    Antwort2.backgroundColor = UIColor.red 
    Antwort3.backgroundColor = UIColor.red 
    Antwort4.backgroundColor = UIColor.red 

    Ende.text = "" 

    FragenSammlung() 
} 

Ces lignes ne seront pas exécutées:

Antwort4.backgroundColor = UIColor.green 

Ende.text = "Richtig!" 

Pourquoi appeler le sommeil le blocage de ces actions? Si je supprime le import Darwin et le sleep, mon code fonctionne correctement. Quelqu'un a-t-il une idée? Désolé pour mon mauvais anglais: P

+1

N'utilisez pas 'sleep' ou des variantes. Vous bloquez le fil principal en ne faisant rien. Utilisez ['dispatch_after'] (https://developer.apple.com/reference/dispatch/1452876-dispatch_after) – jcaron

Répondre

2

Autres alrady répondu à la question, je voulais juste fournir quelques informations supplémentaires (ne peut pas encore commenter).

Vous avez dit que Antwort4.backgroundColor = UIColor.green n'est pas exécuté. Pour clarifier, ceci est exécuté, mais vous ne voyez pas le résultat car vous appelez sleep, ce qui bloque l'interface utilisateur. Voici ce qui se passe:

  1. ensemble couleur de fond de Antwort4 au vert
  2. sommeil: bloquer l'interface utilisateur qui empêche l'application de montrer en fait le fond vert
  3. définir la couleur de fond de Antwort4 à nouveau rouge

Pour résoudre le problème, vous pouvez utiliser les pommes Displatch API. Ainsi, au lieu de dormir, vous pouvez utiliser:

DispatchQueue.main.asyncAfter(deadline: .now() + 1) { 
    self.Antwort1.backgroundColor = UIColor.red 
    self.Antwort2.backgroundColor = UIColor.red 
    self.Antwort3.backgroundColor = UIColor.red 
    self.Antwort4.backgroundColor = UIColor.red 

    self.Ende.text = "" 

    self.FragenSammlung() 
} 
1

La fonction usleep() bloquera votre interface utilisateur. Si vous ne souhaitez pas améliorer ce comportement, utilisez la classe Timer.

3

comme @jcaron dit

ici le code pour le faire:

func delay(delayTime: Double, completionHandler handler:@escaping() ->()) { 
     let newDelay = DispatchTime.now() + delayTime 
     DispatchQueue.main.asyncAfter(deadline: newDelay, execute: handler) 
    } 

Modifié: vous pouvez créer une extension viewController à utiliser dans tout viewControllers comme ceci:

extension UIViewController { 

    func delay(delayTime: Double, completionHandler handler:@escaping() ->()) { 
      let newDelay = DispatchTime.now() + delayTime 
      DispatchQueue.main.asyncAfter(deadline: newDelay, execute: handler) 
     } 
} 

Alors dans votre vueController vous venez d'appeler comme ceci:

delay(delayTime: 2, completionHandler: { 
      _ in 
      // do your code here 
     }) 
+0

merci beaucoup, mais il y a une chose que je ne sais pas: P ce que je dois utiliser comme deuxième paramètre dans delay (2,?) –

+0

Le deuxième paramètre est la fermeture, vous l'utilisez pour retourner la fonction à celui qui l'appelle après la fin du délai. Vous revenez ici exécuter: gestionnaire). J'ai changé le code pour que vous puissiez l'utiliser dans n'importe quel viewControllers sans avoir à créer de nouveau la fonction. –