48 votes

Comment attendre en Objective-C et Swift

Je veux changer mon UILabel après 2 secondes.

J'ai essayé de régler mon UILabel Le texte de l'auteur à "Un texte" et utiliser sleep(2) et enfin changer le texte en "Un autre texte" .

Mais sleep(2) ne fait que geler l'application et "Un autre texte" est réglé sans afficher "Un texte" pendant 2 secondes.

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

0 votes

88voto

Robert Yi Jiang Points 679

Je sais que je suis en retard pour cette fête. Mais je trouve que les gens n'ont pas mentionné le thread sleep. 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 (Feb 2015)

Je pense que le NSTimer est une excellente solution. Ma solution ne fait que donner 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];

Dans la classe, vous avez besoin de cette méthode :

- (void) doSomethingWhenTimeIsUp:(NSTimer*)t {
  // YES! Do something here!!
}

Edition 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)

Elle crée une entité NSTimer et ajoute automatiquement le timer à la NSRunLoop associée au NSThread dans lequel le timer est créé.

Édition 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 (Oct 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
}

Édition 6 (mai 2018) Sur 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
}

44voto

Michał Zygar Points 2686

Vous pouvez utiliser

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

ou si vous voulez l'afficher périodiquement, cochez l'option NSTimer classe.

30voto

0x7fffffff Points 40133

Grand Central Dispatch dispose d'une fonction d'aide 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 la fonction dispatch_queue_t à exécuter. Vous pouvez utiliser dispatch_get_main_queue() à 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
});

Sur Swift 3 l'exemple ci-dessus peut être écrit comme suit :

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

12voto

Srikar Appal Points 26892

Vous pouvez utiliser NSTimer comme ça.

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

Définir une autre méthode updateLabel et faire la mise à jour là. Définissez votre timeInterval en fonction de vos besoins...

Fixation également repeats à YES s'assure que ce sélecteur est exécuté toutes les 0,5 secondes (dans le cas ci-dessus).

5voto

George Johnston Points 17237

Vous pouvez y parvenir avec un minuteur, par exemple.

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
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X