web-dev-qa-db-fra.com

Comment attendre en Objective-C et Swift

Je veux changer le texte de mon UILabel après 2 secondes.

J'ai essayé de définir le texte de mon UILabel sur "A text", et d'utiliser sleep(2) et enfin de changer le texte en "Another text" .

Mais sleep(2) ne gèle que l'application et "Un autre texte" est défini sans afficher "Un texte" pendant 2 secondes.

Comment puis-je afficher "Un texte" pendant 2 secondes, puis afficher "Un autre texte"?

43
jylee

Vous pouvez utiliser

[self performSelector:@selector(changeText:) withObject:text afterDelay:2.0];

ou si vous souhaitez l'afficher périodiquement, cochez la classe NSTimer .

40
Michał Zygar

Je sais que je suis en retard à cette fête. Mais j'ai trouvé que les gens n'avaient pas mentionné le sommeil des fils. Si vous utilisez GCD pour appeler cette fonction. Vous pouvez utiliser :

[NSThread sleepForTimeInterval:2.0f];   

pour retarder le fil pendant 2 secondes.

[self changeText: @"A text"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //Here your non-main thread.
        [NSThread sleepForTimeInterval:2.0f];   
        dispatch_async(dispatch_get_main_queue(), ^{
            //Here you returns to main thread.
            [self changeText: @"Another text"];
        });
    });

Edit 2 (février 2015):

Je pense que le NSTimer est une excellente solution. Ma solution donne juste une autre option pour atteindre l'objectif de NSTimer.

Veuillez lire: Comment utiliser NSTimer?

[NSTimer scheduledTimerWithTimeInterval:2.0
                                 target:self
                               selector:@selector(doSomethingWhenTimeIsUp:)
                               userInfo:nil
                                repeats:NO];

En classe, vous avez besoin de cette méthode:

- (void) doSomethingWhenTimeIsUp:(NSTimer*)t {

        // YES! Do something here!!

}

Edit 3 (mai 2016):

Dans Swift 2.0, vous pouvez utiliser cette méthode:

 NSTimer.scheduledTimerWithTimeInterval(2.0, 
                                         target: self, 
                                       selector: "doSomethingWhenTimeIsUp:", 
                                       userInfo: nil, 
                                        repeats: false)

Il crée une entité NSTimer et ajoute automatiquement le minuteur au NSRunLoop associé au NSThread dans lequel le minuteur est créé.

Edit 4 (juin 2016):

Dans Swift 2.2, la façon d'invoquer select est:

#selector(doSomethingWhenTimeIsUp(_:))

Donc, c'est quelque chose comme:

  NSTimer.scheduledTimerWithTimeInterval(2.0,
                                      target: self,
                                      selector: #selector(doSomethingWhenTimeIsUp()),
                                      userInfo: nil,
                                      repeats: false)

Edit 5 (octobre 2016):

Dans Swift 3, la façon d'invoquer select est:

#selector(doSomethingWhenTimeIsUp)

Donc, c'est quelque chose comme:

        Timer.scheduledTimer(timeInterval: 2.0,
                             target: self,
                             selector:#selector(doSomethingWhenTimeIsUp),
                             userInfo: nil,
                             repeats: false)

Ensuite, le func devrait ressembler à ceci:

        @objc private func doSomethingWhenTimeIsUp(){
        // Do something when time is up
        }

Edit 6 (mai 2018):

Dans Swift 4 , nous pouvons faire comme ci-dessous.

    let delaySeconds = 2.0
    DispatchQueue.main.asyncAfter(deadline: .now() + delaySeconds) {
        doSomethingWhenTimeIsUp()
    }  

Ensuite, le func devrait ressembler à ceci:

    private func doSomethingWhenTimeIsUp(){
        // Do something when time is up
        }
80
Yi Jiang

Grand Central Dispatch a une fonction d'assistance dispatch_after() pour effectuer des opérations après un délai qui peut être très utile. Vous pouvez spécifier le temps d'attente avant l'exécution et l'instance dispatch_queue_t Pour s'exécuter. Vous pouvez utiliser dispatch_get_main_queue() pour exécuter sur le thread principal (UI).

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    // do something
});

Dans Swift, l'exemple ci-dessus peut s'écrire:

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    // do something
}
28
Mick MacCallum

Vous pouvez utiliser NSTimer, comme ça -

[NSTimer scheduledTimerWithTimeInterval:0.5 
                                 target:self 
                               selector:@selector(updateLabel:) 
                               userInfo:nil 
                                repeats:YES];

Définissez une autre méthode updateLabel et effectuez la mise à jour à cet endroit. Définissez votre intervalle de temps pour répondre à vos besoins ...

La définition de repeats sur YES garantit que ce sélecteur est exécuté toutes les 0,5 secondes (dans le cas ci-dessus).

12
Srikar Appalaraju

Vous pouvez accomplir cela avec une minuterie, par ex.

   NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:@selector(eventToFire:) userInfo:nil repeats:YES]; // Fire every 4 seconds.

   ...

   - (void)eventToFire:(NSTimer*)timer {
      // Do Something
   }
5
George Johnston

En effet, la vue n'est pas mise à jour jusqu'à la fin de la boucle d'exécution. Au lieu d'utiliser les modes veille, essayez d'utiliser NSTimer pour définir une heure spécifique pour mettre à jour la vue.

2
Dave

Vous devez utiliser une minuterie. L'utilisation du sommeil interrompra l'intégralité de votre programme. Vérifiez NSTimer

2
Pepe

La méthode suivante est bonne.

Vous pouvez remplacer votre

sommeil (1);

avec

dispatch_semaphore_t semaphore = dispatch_semaphore_create (0); dispatch_semaphore_wait (sémaphore, dispatch_time (DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC));

0
JateXu