ios - timer.scheduledtimer swift 4 example
¿Cómo puedo usar NSTimer en Swift? (12)
SimpleTimer (Swift 3.1)
¿Por qué?
Esta es una clase de temporizador simple en swift que le permite:
- Temporizador de ámbito local
- Chainable
- Un trazadores de líneas
- Utilice devoluciones de llamada regulares
Uso:
SimpleTimer(interval: 3,repeats: true){print("tick")}.start()//Ticks every 3 secs
Código:
class SimpleTimer {/*<--was named Timer, but since swift 3, NSTimer is now Timer*/
typealias Tick = ()->Void
var timer:Timer?
var interval:TimeInterval /*in seconds*/
var repeats:Bool
var tick:Tick
init( interval:TimeInterval, repeats:Bool = false, onTick:@escaping Tick){
self.interval = interval
self.repeats = repeats
self.tick = onTick
}
func start(){
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(update), userInfo: nil, repeats: true)//swift 3 upgrade
}
func stop(){
if(timer != nil){timer!.invalidate()}
}
/**
* This method must be in the public or scope
*/
@objc func update() {
tick()
}
}
Lo intenté
var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)
Pero, tengo un error diciendo
''(timeInterval: $T1, target: ViewController, selector: () -> (), userInfo: NilType, repeats: Bool) -> $T6'' is not identical to ''NSTimer''
A partir de iOS 10 también hay un nuevo método de fábrica Timer basado en bloques que es más limpio que usar el selector:
_ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
label.isHidden = true
}
Actualizado a Swift 4, aprovechando la información de usuario:
class TimerSample {
var timer: Timer?
func startTimer() {
timer = Timer.scheduledTimer(timeInterval: 5.0,
target: self,
selector: #selector(eventWith(timer:)),
userInfo: [ "foo" : "bar" ],
repeats: true)
}
// Timer expects @objc selector
@objc func eventWith(timer: Timer!) {
let info = timer.userInfo as Any
print(info)
}
}
Aquí hay algunos ejemplos más completos actualizados para Swift 3 .
Evento repetido
Puede usar un temporizador para realizar una acción varias veces, como se ve en el siguiente ejemplo. El temporizador llama a un método para actualizar una etiqueta cada medio segundo.
Aquí está el código para eso:
import UIKit
class ViewController: UIViewController {
var counter = 0
var timer = Timer()
@IBOutlet weak var label: UILabel!
// start timer
@IBAction func startTimerButtonTapped(sender: UIButton) {
timer.invalidate() // just in case this button is tapped multiple times
// start the timer
timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
}
// stop timer
@IBAction func cancelTimerButtonTapped(sender: UIButton) {
timer.invalidate()
}
// called every time interval from the timer
func timerAction() {
counter += 1
label.text = "/(counter)"
}
}
Evento retrasado
También puede usar un temporizador para programar un evento puntual en el futuro. La principal diferencia con el ejemplo anterior es que utiliza repeats: false
lugar de true
.
timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
El ejemplo anterior llama a un método llamado delayedAction
dos segundos después de configurar el temporizador. No se repite, pero aún puede llamar a timer.invalidate()
si necesita cancelar el evento antes de que suceda.
Notas
- Si hay alguna posibilidad de iniciar su instancia del temporizador varias veces, asegúrese de que primero invalida la instancia del temporizador anterior. De lo contrario, perderá la referencia al temporizador y no podrá detenerlo más. (vea estas preguntas y respuestas )
- No use temporizadores cuando no son necesarios. Consulte la sección de temporizadores de la Guía de Eficiencia Energética para Aplicaciones iOS .
Relacionado
- Cómo trabajar con fechas y horas en Swift
Comprueba con:
var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("update"), userInfo: nil, repeats: true);
Deberá usar el Timer lugar de NSTimer en Swift 3.
Aquí hay un ejemplo:
Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(YourController.update),
userInfo: nil,
repeats: true)
// @objc selector expected for Timer
@objc func update() {
// do what should happen when timer triggers an event
}
En Swift 3 algo como esto con @objc:
func startTimerForResendingCode() {
let timerIntervalForResendingCode = TimeInterval(60)
Timer.scheduledTimer(timeInterval: timerIntervalForResendingCode,
target: self,
selector: #selector(timerEndedUp),
userInfo: nil,
repeats: false)
}
@objc func timerEndedUp() {
output?.timerHasFinishedAndCodeMayBeResended()
}
Esto funcionará:
override func viewDidLoad() {
super.viewDidLoad()
// Swift block syntax (iOS 10+)
let timer = Timer(timeInterval: 0.4, repeats: true) { _ in print("Done!") }
// Swift >=3 selector syntax
let timer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
// Swift 2.2 selector syntax
let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyClass.update), userInfo: nil, repeats: true)
// Swift <2.2 selector syntax
let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "update", userInfo: nil, repeats: true)
}
// must be internal or public.
@objc func update() {
// Something cool
}
Para Swift 4, el método del cual desea obtener el selector debe estar expuesto a Objective-C, por @objc
atributo @objc
debe agregarse a la declaración del método.
Si inicia método de temporizador
let timer = Timer(timeInterval: 3, target: self, selector: #selector(update(_:)), userInfo: [key : value], repeats: false)
func update(_ timer : Timer) {
}
Luego agréguelo al bucle usando el método de otro selector que no será llamado
RunLoop.main.add(timer!, forMode: .defaultRunLoopMode)
NOTA: Si desea que esto se repita, haga las repeticiones verdaderas y mantenga la referencia del temporizador, de lo contrario, no se llamará al método de actualización.
Si está utilizando este método.
Timer.scheduledTimer(timeInterval: seconds, target: self, selector: #selector(update(_:)), userInfo: nil, repeats: true)
mantener una referencia para su uso posterior si las repeticiones son verdaderas.
Swift 3, pre iOS 10
func schedule() {
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(timeInterval: 20, target: self,
selector: #selector(self.timerDidFire(timer:)), userInfo: nil, repeats: false)
}
}
@objc private func timerDidFire(timer: Timer) {
print(timer)
}
Swift 3, iOS 10+
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(withTimeInterval: 20, repeats: false) { timer in
print(timer)
}
}
Notas
- Necesita estar en la cola principal.
- La función de devolución de llamada puede ser pública, privada, ...
- La función de devolución de llamada debe ser
@objc
para swift 3 y Xcode 8.2 (es bueno tener bloques, pero si compilas para iOS9 Y quieres userInfo):
...
self.timer = Timer(fireAt: fire,
interval: deltaT,
target: self,
selector: #selector(timerCallBack(timer:)),
userInfo: ["custom":"data"],
repeats: true)
RunLoop.main.add(self.timer!, forMode: RunLoopMode.commonModes)
self.timer!.fire()
}
func timerCallBack(timer: Timer!){
let info = timer.userInfo
print(info)
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)
Y crear diversión por el nombre createEnemy
fund createEnemy ()
{
do anything ////
}