ios - dispatch_async - Cómo programar un retraso en Swift 3
delay swift 4 (6)
En versiones anteriores de Swift, uno podría crear un retraso con el siguiente código:
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
}
Pero ahora, en Swift 3, Xcode cambia automáticamente 6 cosas diferentes, pero luego aparece el siguiente error: "No se puede convertir
DispatchTime.now
al valor esperado
dispatch_time_t
aka
UInt64
".
¿Cómo se puede crear un retraso antes de ejecutar una secuencia de código en Swift 3?
// Ejecuta la función después de x segundos
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)
}
//Utilizar:-
runThisAfterDelay(seconds: x){
//write your code here
}
Después de mucha investigación, finalmente descubrí esto.
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
// Code you want to be delayed
}
Esto crea el efecto de "espera" deseado en Swift 3 y Swift 4.
Inspirado por una parte de esta respuesta .
Me gusta la notación de una línea para GCD, es más elegante:
DispatchQueue.main.asyncAfter(deadline: .now() + 42.0) {
// do stuff 42 seconds later
}
Además, en iOS 10 tenemos nuevos métodos de temporizador, por ejemplo, inicializador de bloque:
(por lo que la acción retrasada puede cancelarse)
let timer = Timer.scheduledTimer(withTimeInterval: 42.0, repeats: false) { (timer) in
// do stuff 42 seconds later
}
Por cierto, tenga en cuenta: de manera predeterminada, el temporizador se agrega al modo de ciclo de ejecución predeterminado. Significa que el temporizador puede congelarse cuando este modo de bucle está en espera (por ejemplo, cuando se desplaza un UIScrollView). Puede resolver este problema agregando el temporizador al modo de bucle de ejecución específico:
RunLoop.current.add(timer, forMode: .commonModes)
En esta publicación de blog puedes encontrar más detalles.
Pruebe el siguiente código para retrasos
//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
}
Pruebe la siguiente función implementada en Swift 3.0 y superior
func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
Uso
delayWithSeconds(1) {
//Do something
}
Una forma es usar
DispatchQueue.main.asyncAfter
ya que muchas personas han respondido.
Otra forma es usar
perform(_:with:afterDelay:)
.
Más detalles aquí
perform(#selector(delayedFunc), with: nil, afterDelay: 3)
@IBAction func delayedFunc() {
// implement code
}