web-dev-qa-db-fra.com

Comment programmer un retard dans Swift 3

Dans les versions antérieures de Swift, il était possible de créer un délai avec le code suivant:

let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 4 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
    //put your code which should be executed with a delay here
}

Mais maintenant, dans Swift 3, Xcode change automatiquement 6 choses différentes, mais l'erreur suivante apparaît: "Impossible de convertir DispatchTime.now en valeur attendue dispatch_time_t aka UInt64.". "

Comment créer un délai avant d'exécuter une séquence de code dans Swift 3?

283
owlswipe

Après de nombreuses recherches, j'ai finalement trouvé celui-ci.

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
   // Code you want to be delayed
}

Cela crée l'effet "attente" souhaité dans Swift 3 et Swift 4.

Inspiré par une partie de cette réponse .

846
owlswipe

J'aime la notation sur une ligne pour GCD, c'est plus élégant:

    DispatchQueue.main.asyncAfter(deadline: .now() + 42.0) {
        // do stuff 42 seconds later
    }

De plus, dans iOS 10, nous avons de nouvelles méthodes de minuterie, par exemple. bloc initialiseur:

(action retardée peut être annulée)

    let timer = Timer.scheduledTimer(withTimeInterval: 42.0, repeats: false) { (timer) in
        // do stuff 42 seconds later
    }

Btw, gardez à l'esprit: par défaut, la minuterie est ajoutée au mode de boucle d'exécution par défaut. Cela signifie que le minuteur peut être gelé lorsque ce mode boucle est en attente (par exemple, lors du défilement d'un UIScrollView). Vous pouvez résoudre ce problème en ajoutant le minuteur au mode spécifique d'exécution en boucle:

RunLoop.current.add(timer, forMode: .commonModes)

À ce article de blog vous pouvez trouver plus de détails.

130
Victor Do

Essayez la fonction suivante implémentée dans Swift 3.0 et supérieur

func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds) { 
        completion()
    }
}

Usage

delayWithSeconds(1) {
   //Do something
}
51
Vakas

Essayez le code ci-dessous pour retarder

//MARK: First Way

func delayForWork() {
    delay(3.0) {
        print("delay for 3.0 second")
    }
}

delayForWork()

// MARK: Second Way

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    // your code here delayed by 0.5 seconds
}
28
Anand Verma

Une solution consiste à utiliser DispatchQueue.main.asyncAfter comme beaucoup de personnes l’ont répondu.

Une autre façon consiste à utiliser perform(_:with:afterDelay:). Plus de détails ici

perform(#selector(delayedFunc), with: nil, afterDelay: 3)

@IBAction func delayedFunc() {
    // implement code
}
1
Zohaib Brohi

// Fonctionne après x secondes

public static func runThisAfterDelay(seconds: Double, after: @escaping () -> Void) {
    runThisAfterDelay(seconds: seconds, queue: DispatchQueue.main, after: after)
}

public static func runThisAfterDelay(seconds: Double, queue: DispatchQueue, after: @escaping () -> Void) {
    let time = DispatchTime.now() + Double(Int64(seconds * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
    queue.asyncAfter(deadline: time, execute: after)
}

//Utilisation:-

runThisAfterDelay(seconds: x){
  //write your code here
}
1
Pratyush Pratik