web-dev-qa-db-fra.com

Actions différées dans Swift

Je veux faire en sorte qu'un indicateur d'activité commence à s'animer puis s'arrête après une seconde.

Est-ce que quelqu'un sait comment je pourrais faire ça?

class stuff {
@IBOutlet weak var indicator: UIActivityIndicatorView!

   func iGotTriggeredBySomething {
      indicator.startAimating()
      //delay?
      indicator.stopAnimating()
   }
}

Merci de répondre.

29
user4001326

dispatch_after() est le moyen standard de retarder les actions.

indicator.startAnimating()

let delay = 4.5 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue()) {
    indicator.stopAnimating()
}

Voir: dispatch_after - GCD en rapide?


Mise à jour pour Swift 3.0

indicator.startAnimating()

let delay = Int(4.5 * Double(1000))
DispatchQueue.main.after(when: .now() + .milliseconds(delay)) {
    indicator.stopAnimating()
}

Cependant, dans l'esprit de Swift 3.0, je pense que l'extension de DispatchQueue serait une meilleure solution.

extension DispatchQueue {
    func delay(_ timeInterval: TimeInterval, execute work: () -> Void) {
        let milliseconds = Int(timeInterval * Double(1000))
        after(when: .now() + .milliseconds(milliseconds), execute: work)
    }
}

Cela nous laisse avec une très belle

indicator.startAnimating()

DispatchQueue.main.delay(4.5) {
    indicator.stopAnimating()
}

Mise à jour 2

En creusant dans la version bêta de Xcode 8.0, j'ai trouvé public func +(time: DispatchTime, seconds: Double) -> DispatchTime. Donc, je suppose que c'est valable…

indicator.startAnimating()

DispatchQueue.main.after(when: .now() + 4.5) {
    indicator.stopAnimating()
}

Je ne pense pas qu'il soit déjà nécessaire d'étendre DispatchQueue pour quelque chose d'aussi propre.

-

Mise à jour pour Swift 3.1

Il y a une nouvelle syntaxe pour Swift 3.1. Ils aiment juste changer les choses non?.

indicator.startAnimating()

DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
    indicator.stopAnimating()
}
79
Jeffery Thomas

Avec la syntaxe Swift 3 mise à jour, cela devient

DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
    indicator.stopAnimating()
}
10
Matt Weinecke

Voici un code plus propre et plus expressif pour ce faire en utilisant Swift 3.1 et Grand Central Dispatch:

Swift 3.1:

indicator.startAnimating()

// Runs after 1 second on the main queue.
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1) ) { 
    indicator.stopAnimating()
}

.seconds(Int), .microseconds(Int) et .nanoseconds(Int) peuvent également être utilisés pour l'heure.

9
Hannes Sverrisson

Nouveau dans iOS 10, Timer a un initialiseur de bloc qui s'exécute sur le thread principal. Il est également légèrement plus flexible, car vous pouvez prendre une référence à la minuterie et l'annuler ou la replanifier après coup.

    let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) {_ in 
    }
3
Josh Homann