Programación en Swift y SwiftUI para iOS Developers

SwiftUI Timer

Para ejecutar algún código de forma automática, tal vez para crear un reloj de inicio o similar, debe utilizar Timer y el modificador onReceive().

La capacidad de ejecutar código ocasionalmente es una tarea importante en el desarrollo iOS.

Por ejemplo, este código crea un timer que se activa constantemente y actualiza una etiqueta con el tiempo en curso:

Cómo usar el timer en SwiftUI

Haces un temporizador y escúchalo con el modificador .onReceive.

struct ContentView: View {
    @State var startDate = Date.now
    @State var timeElapsed: Int = 0
    
    // 1
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    
    var body: some View {
        Text("Time elapsed: \(timeElapsed) sec")
            // 2
            .onReceive(timer) { firedDate in

                print("timer fired")
                // 3
                timeElapsed = Int(firedDate.timeIntervalSince(startDate))

            }
            .font(.largeTitle)
    }
}
  1. Creamos un timer utilizando Timer.publish(every: 1, on: .primary, in: .common).autoconnect(). Para esta situación, creemos que nuestro reloj debería adelantarse cada segundo. Lo ejecutamos en el círculo de ejecución .main ya que lo usamos para actualizar la interfaz de usuario. El último límite es ejecutar el modo círculo, puedes pensarlo como una especie de necesidad. Para cosas relacionadas con la interfaz de usuario, utiliza el bucle de ejecución .common. La parte .autoconnect() le indica al timer que comience una vez que le prestamos atención.
  2. Prestamos atención a un timer que utiliza el modificador .onReceive.
  3. En consecuencia, una conclusión onReceive se activará con un límite de fecha de finalización. Utilizamos esto para calcular el tiempo transcurrido en esta situación.

Significa mucho usar .primary para la opción runloop, porque nuestro temporizador o timer actualizará la interfaz de usuario. En cuanto al modo .familiar, esto permite que el reloj avance en otras ocasiones normales, por ejemplo, suponiendo que el texto estaba en una vista de pergamino en movimiento.

Como puede resultar obvio, la conclusión de onReceive() se pasa en alguna información que contiene la fecha en curso. En el código anterior lo relegamos directamente a fecha actual, pero puedes utilizarlo para calcular cuánto tiempo ha pasado desde una fecha pasada.

Para crear un cronómetro o cronómetro de inicio, debe establecer un estado para seguir la duración de los elementos restantes y luego, en ese momento, descontar de eso el momento en que se activa el cronómetro.

Cómo cancelar el temporizador en SwiftUI

Para cancelar o detener un temporizador, utilice timer.upstream.connect().cancel().

Podemos agregar un botón Detener al timer:

struct ContentView: View {
    @State var startDate = Date.now
    @State var timeElapsed: Int = 0
    
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        VStack {
            Text("Time elapsed: \(timeElapsed) sec")
                .onReceive(timer) { firedDate in
                    print("timer fired")
                    timeElapsed = Int(firedDate.timeIntervalSince(startDate))
                }
            Button("Stop") {

                timer.upstream.connect().cancel()
            }
        }
        .font(.largeTitle)        
    }
}

Reiniciar un temporizador en SwiftUI

La mejor manera de reiniciar un timer es reproducirlo y volver a conectarlo.

En este ejemplo, reproducimos un temporizador en la actividad del botón Resume

struct ContentView: View {
    @State var startDate = Date.now
    @State var timeElapsed: Int = 0
    
    // 1
    @State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    
    var body: some View {
        VStack {
            Text("Time elapsed: \(timeElapsed) sec")
                .onReceive(timer) { firedDate in
                    print("timer fired")
                    timeElapsed = Int(firedDate.timeIntervalSince(startDate))
                }
            Button("Pause") {
                timer.upstream.connect().cancel()
            }
            Button("Resume") {
                // 2
                timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

            }
        }
        .font(.largeTitle)
    }
}
  1. We need to have the option to reproduce a timer, so we change from let to @State var.
  2. Agregamos un botón para reproducir un timer.
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Article

Combinando shapes en SwiftUI

Next Article

Cambiar el color de la Navigation Bar en SwiftUI

Related Posts