J'ai essayé
var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)
Mais, j'ai une erreur en disant
'(timeInterval: $T1, target: ViewController, selector: () -> (), userInfo: NilType, repeats: Bool) -> $T6' is not identical to 'NSTimer'
Cela fonctionnera:
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
}
Pour Swift 4, la méthode dont vous voulez obtenir le sélecteur doit être exposée à Objective-C, ainsi l'attribut @objc
doit être ajouté à la déclaration de méthode.
Vous pouvez utiliser un minuteur pour effectuer une action plusieurs fois, comme illustré dans l'exemple suivant. Le minuteur appelle une méthode pour mettre à jour une étiquette toutes les demi-secondes.
Voici le code pour cela:
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)"
}
}
Vous pouvez également utiliser une minuterie pour planifier un événement ponctuel dans le futur. La principale différence avec l'exemple ci-dessus est que vous utilisez repeats: false
au lieu de true
.
timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
L'exemple ci-dessus appelle une méthode nommée delayedAction
deux secondes après le réglage de la minuterie. Il ne se répète pas, mais vous pouvez toujours appeler timer.invalidate()
si vous devez annuler l'événement avant qu'il ne se produise.
Mis à jour à Swift 4, utilisant userInfo:
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)
}
}
Depuis iOS 10, il existe également une nouvelle méthode de fabrique de minuterie basée sur des blocs qui est plus propre que d'utiliser le sélecteur:
_ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
label.isHidden = true
}
Swift 3, pré 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)
}
}
Remarques
@objc
Vérifier avec:
Swift 2
var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
Swift 3, 4, 5
var timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
Vous devrez utiliser Minuteur au lieu de NSTimer dans Swift 3.
Voici un exemple:
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
}
for Swift 3 et Xcode 8.2 (C'est bien d'avoir des blocs, mais si vous compilez pour iOS9 ET voulez 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)
}
Il s'agit d'une classe de minuterie simple dans Swift qui vous permet de:
SimpleTimer(interval: 3,repeats: true){print("tick")}.start()//Ticks every 3 secs
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()
}
}
Dans Swift quelque chose comme ceci avec @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()
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)
Et créer de l'amusement par le nom createEnemy
fund createEnemy ()
{
do anything ////
}
Si vous initiez la méthode du timer
let timer = Timer(timeInterval: 3, target: self, selector: #selector(update(_:)), userInfo: [key : value], repeats: false)
func update(_ timer : Timer) {
}
puis ajoutez-le à la boucle en utilisant la méthode autre sélecteur ne sera pas appelé
RunLoop.main.add(timer!, forMode: .defaultRunLoopMode)
NOTE: Si vous voulez que cela répète, make répète vrai et conserve la référence du temporisateur, sinon la méthode update ne sera pas appelée.
Si vous utilisez cette méthode.
Timer.scheduledTimer(timeInterval: seconds, target: self, selector: #selector(update(_:)), userInfo: nil, repeats: true)
conservez une référence pour une utilisation ultérieure si répétitions est vraie.