Swift IF statement to perform action only once - swift

I have an IF statement and I need it to trigger when the score >= 200 but only happen once and not repeatedly.
Here's my code:
if score >= 200 {
meteRedTimer.invalidate()
meteBlueTimer = Timer.scheduledTimer(timeInterval: 0.7, target: self, selector: #selector(self.makeBlueMete), userInfo: nil, repeats: true)
} else {
}
However this constantly starts the timer all the time when the score is => 200 and not just one timer which I understand.
If I do score = 200 this would work however there is a chance the score could jump from 190 to 210 for example depending on the game play.
How could I basically stop this IF statement once it has been triggered once?

Make sure meteBlueTimer is declared as optional.
var meteBlueTimer: Timer?
Then simply check if it is nil or not.
if score >= 200 {
if meteBlueTimer == nil {
meteRedTimer.invalidate()
meteBlueTimer = Timer.scheduledTimer(timeInterval: 0.7, target: self, selector: #selector(self.makeBlueMete), userInfo: nil, repeats: true)
}
} else {
}
This way you only create the meteBlueTimer once.

create var didPermored = false and inside if statement
if score >= 200 && !didPermormed {
didPermormed = true
meteRedTimer.invalidate()
meteBlueTimer = Timer.scheduledTimer(timeInterval: 0.7, target: self, selector: #selector(self.makeBlueMete), userInfo: nil, repeats: true)
} else {
//do stuff
}

Declare your timers as optional
var meteBlueTimer : Timer?
var meteRedTimer : Timer?
Then check if the timer is not running (nil). Set the invalidated timers to nil.
if score >= 200 && meteBlueTimer == nil {
meteRedTimer?.invalidate()
meteRedTimer = nil
meteBlueTimer = Timer.scheduledTimer(timeInterval: 0.7, target: self, selector: #selector(self.makeBlueMete), userInfo: nil, repeats: true)
} else { ...

Related

ScheduledTimer selector. Objective-c or Swift? [duplicate]

I tried
var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)
But, I got an error saying
'(timeInterval: $T1, target: ViewController, selector: () -> (), userInfo: NilType, repeats: Bool) -> $T6' is not identical to 'NSTimer'
This will work:
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
}
For Swift 4, the method of which you want to get the selector must be exposed to Objective-C, thus #objc attribute must be added to the method declaration.
Repeated event
You can use a timer to do an action multiple times, as seen in the following example. The timer calls a method to update a label every half second.
Here is the code for that:
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)"
}
}
Delayed event
You can also use a timer to schedule a one time event for some time in the future. The main difference from the above example is that you use repeats: false instead of true.
timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
The above example calls a method named delayedAction two seconds after the timer is set. It is not repeated, but you can still call timer.invalidate() if you need to cancel the event before it ever happens.
Notes
If there is any chance of starting your timer instance multiple times, be sure that you invalidate the old timer instance first. Otherwise you lose the reference to the timer and you can't stop it anymore. (see this Q&A)
Don't use timers when they aren't needed. See the timers section of the Energy Efficiency Guide for iOS Apps.
Related
How to work with dates and time in Swift
Updated to Swift 4, leveraging 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)
}
}
As of iOS 10 there is also a new block based Timer factory method which is cleaner than using the selector:
_ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
label.isHidden = true
}
Swift 5
I personally prefer the Timer with the block closure:
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
// TODO: - whatever you want
}
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)
}
}
Notes
It needs to be on the main queue
Callback function can be public, private, ...
Callback function needs to be #objc
Check with:
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)
You will need to use Timer instead of NSTimer in Swift 3.
Here is an example:
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
}
First declare your timer
var timer: Timer?
Then add line in viewDidLoad() or in any function you want to start the timer
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(action), userInfo: nil, repeats: false)
This is the func you will callback it to do something it must be #objc
#objc func action () {
print("done")
}
for swift 3 and Xcode 8.2
(nice to have blocks, but if You compile for iOS9 AND want 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)
}
SimpleTimer (Swift 3.1)
Why?
This is a simple timer class in swift that enables you to:
Local scoped timer
Chainable
One liners
Use regular callbacks
Usage:
SimpleTimer(interval: 3,repeats: true){print("tick")}.start()//Ticks every 3 secs
Code:
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()
}
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)
And Create Fun By The Name createEnemy
fund createEnemy ()
{
do anything ////
}
In Swift 3 something like this with #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()
}
If you init method of timer
let timer = Timer(timeInterval: 3, target: self, selector: #selector(update(_:)), userInfo: [key : value], repeats: false)
func update(_ timer : Timer) {
}
then add it to loop using method other selector will not be called
RunLoop.main.add(timer!, forMode: .defaultRunLoopMode)
NOTE : If you are want this to repeat make repeats true and keep the reference of timer otherwise update method will not be called.
If you are using this method.
Timer.scheduledTimer(timeInterval: seconds, target: self, selector: #selector(update(_:)), userInfo: nil, repeats: true)
keep a reference for later use if repeats is true.
I tried to do in a NSObject Class and this worked for me:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
print("Bang!") }
NSTimer has been renamed to Timer in Swift 4.2.
this syntax will work in 4.2:
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(UIMenuController.update), userInfo: nil, repeats: true)

Swift 3 Timer in a Class not firing

I have a class:
class GameManager {...
and within it I have this func:
func startGame() {
msgTimer = Timer(timeInterval: 0.5, target: self, selector: #selector(typeMessage(_:)), userInfo: nil, repeats: true)
}
and the selector it calls:
#objc func typeMessage(_ sender:Timer) {
if textCount > strInitText.characters.count {
let strThisChar = strInitText[strInitText.index(strInitText.startIndex, offsetBy: textCount)]
strDisplayText = strDisplayText + String(strThisChar)
print(strDisplayText)
}
}
But the selector never gets called.
Change
msgTimer = Timer(timeInterval: 0.5, target: self, selector: #selector(typeMessage(_:)), userInfo: nil, repeats: true)
to
msgTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(typeMessage(_:)), userInfo: nil, repeats: true)
This timer needs to be scheduled on a run loop (via -[NSRunLoop addTimer:]) before it will fire.
And call it from the main thread as follows:
DispatchQueue.main.async { [weak self] in
self?.msgTimer = Timer(timeInterval: 0.5, target: self, selector: #selector(self.typeMessage(_:)), userInfo: nil, repeats: true)
RunLoop.current.add(self.msgTimer, forMode: RunLoopMode.commonModes)
}
However, I recommend you to use scheduledTimer in this instance to remove this step:
Creates a timer and schedules it on the current run loop in the default mode.
Be sure to invalidate the timer when you are done with it as follows:
self.msgTimer.invalidate()

Timer Won't Call Selector Function

I'm not sure why but every time I run my application, my timer will not call the update function. I have tried everything: using #selector, adding a colon at the end of update, nothing is working. I have added a print statement inside my update to make sure that it reaches there, and the print statement never prints! I'm not sure why it isn't being called.... Help! P.S. I know selected is indeed one of the options in the if statement, I had a print statement for that and it's working.
if (selected == "05 seconds") {
count = 5
timer = Timer(timeInterval: 1.0, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
else if (selected == "10 seconds") {
count = 10
timer = Timer(timeInterval: 1.0, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
else if (selected == "20 seconds") {
count = 20
timer = Timer(timeInterval: 1.0, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
else if (selected == "30 seconds") {
print("I'm here!")
count = 30
timer = Timer(timeInterval: 1.0, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
else if (selected == "Single Shot") {
SendButton.isHidden = false
countDownLabel.isHidden = true
}
}
func update() {
print("Now I'm in update!")
count = count - 1;
countDownLabel.text = String(count)
}
The timer does not work, because the method you are using requires that the timer is explicitly added to the runloop.
Use the API which adds the timer implicitly to the runloop.
DispatchQueue.main.async {
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(update), userInfo: nil, repeats: true)
}
PS: The #selector syntax is preferable because it checks the existence of the action method at compile time.

How can I pause and resume NSTimer.scheduledTimerWithTimeInterval in swift?

I'm developing a game and I want to create a pause menu. Here is my code:
self.view?.paused = true
but NSTimer.scheduledTimerWithTimeInterval still running...
for var i=0; i < rocketCount; i++ {
var a: NSTimeInterval = 1
ii += a
delaysShow = 2.0 + ((stimulus + interStimulus) * ii)
var time3 = NSTimer.scheduledTimerWithTimeInterval(delaysShow!, target: self, selector: Selector("showRocket:"), userInfo: rocketid[i], repeats: false)
}
I want time3 to pause the timer when player click pause menu and continue run the timer when player come back to the game, but how can I pause NSTimer.scheduledTimerWithTimeInterval? help me please.
You need to invalidate it and recreate it. You can then use an isPaused bool to keep track of the state if you have the same button to pause and resume the timer:
var isPaused = true
var timer = NSTimer()
#IBAction func pauseResume(sender: AnyObject) {
if isPaused{
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("somAction"), userInfo: nil, repeats: true)
isPaused = false
} else {
timer.invalidate()
isPaused = true
}
}
To Start:
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateView"), userInfo: nil, repeats: true)
To Resume:
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateView"), userInfo: nil, repeats: true)
To Pause:
timer.invalidate
This worked for me. The trick is that do not look for something like "timer.resume" or "timer.validate". Just use "the same code for starting a timer" to resume it after the pause.
To start
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true)
To pause
timer.invalidate()
To reset
time += 1
label.text = String(time)
'label' is the timer on output.
I was just working through a similar problem with my game, and found an easy solution.
First I should point out like others have, that Timer and NSTimer doesn't have a pause function. You have to stop the Timer with Timer.invalidate(). After invalidating a Timer, you must initialize it again to start the Timer. To quote from https://developer.apple.com/documentation/foundation/timer, the function .invalidate() -
Stops the timer from ever firing again and requests its removal from
its run loop.
To pause a timer we can use Timer.fireDate, this is where Timer (and NSTimer) saves the date for when the Timer will fire in the future.
Here's how we can pause a Timer by saving the seconds left that the Timer has until it fires again.
//The variable we will store the remaining timers time in
var timeUntilFire = TimeInterval()
//The timer to pause
var gameTimer = Timer.scheduledTimer(timeInterval: delaysShow!, target: self, selector: #selector(GameClass.showRocket), userInfo: rocketid[i], repeats: false)
func pauseTimer()
{
//Get the difference in seconds between now and the future fire date
timeUntilFire = gameTimer.fireDate.timeIntervalSinceNow
//Stop the timer
gameTimer.invalidate()
}
func resumeTimer()
{
//Start the timer again with the previously invalidated timers time left with timeUntilFire
gameTimer = Timer.scheduledTimer(timeInterval: timeUntilFire, target: self, selector: #selector(GameClass.showRocket), userInfo: rocketid[i], repeats: false)
}
Note: Don't invalidate() the Timer before getting the fireDate. After invalidate() is called the Timer seems to reset the fireDate to 2001-01-01 00:00:00 +0000.
2nd Note: A timer can potentially fire after its set fireDate. This will lead to a negative number, which will default the Timer to run after 0.1 milliseconds instead. https://developer.apple.com/documentation/foundation/timer/1412416-scheduledtimer
To stop it
time3.invalidate()
To start it again
time3.fire()
You can not resume the timer back.
Instead of resuming - just create a new timer.
class SomeClass : NSObject { // class must be NSObject, if there is no "NSObject" you'll get the error at runtime
var timer = NSTimer()
init() {
super.init()
startOrResumeTimer()
}
func timerAction() {
NSLog("timer action")
}
func pauseTimer() {
timer.invalidate
}
func startOrResumeTimer() {
timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("timerAction"), userInfo: nil, repeats: true)
}
}
Even though the solutions exposed here are good, I thought an important insight was missing. Like a lot of people here explained, timer invalidate() and recreate is the best option. But one could argue that you could do something like this:
var paused:Bool
func timerAction() {
if !paused {
// Do stuff here
}
}
is easier to implement, but it will be less efficient.
For energy impact reasons, Apple promotes avoiding timers whenever possible and to prefer event notifications. If you really need to use a timer, you should implement pauses efficiently by invalidating the current timer. Read recommendations about Timer in the Apple Energy Efficiency Guide here:
https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/MinimizeTimerUse.html
SWIFT3
Global Declaration :
var swiftTimer = Timer()
var count = 30
var timer = Timer()
#IBOutlet weak var CountDownTimer: UILabel!
viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
BtnStart.tag = 0
}
Triggered IBACTION :
#IBAction func BtnStartTapped(_ sender: Any) {
if BtnStart.tag == 0 {
BtnStart.setTitle("STOP", for: .normal)
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ScoreBoardVC.update), userInfo: nil, repeats: true)
BtnStart.tag = 1
} else {
BtnStart.setTitle("START", for: .normal)
timer.invalidate()
BtnStart.tag = 0
}
}
Function that Handles The things :
func update(){
if(count > 0){
let minutes = String(count / 60)
let ConvMin = Float(minutes)
let minuttes1 = String(format: "%.0f", ConvMin!)
print(minutes)
let seconds = String(count % 60)
let ConvSec = Float(seconds)
let seconds1 = String(format: "%.0f", ConvSec!)
CountDownTimer.text = (minuttes1 + ":" + seconds1)
count += 1
}
}
Pause timer : timer.invalidate()
and
Resume timer : recreate timer. it's work fine.
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(mainController.updateTimer), userInfo: nil, repeats: true)

Calling a method after a fixed period of time in swift [duplicate]

I tried
var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)
But, I got an error saying
'(timeInterval: $T1, target: ViewController, selector: () -> (), userInfo: NilType, repeats: Bool) -> $T6' is not identical to 'NSTimer'
This will work:
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
}
For Swift 4, the method of which you want to get the selector must be exposed to Objective-C, thus #objc attribute must be added to the method declaration.
Repeated event
You can use a timer to do an action multiple times, as seen in the following example. The timer calls a method to update a label every half second.
Here is the code for that:
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)"
}
}
Delayed event
You can also use a timer to schedule a one time event for some time in the future. The main difference from the above example is that you use repeats: false instead of true.
timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
The above example calls a method named delayedAction two seconds after the timer is set. It is not repeated, but you can still call timer.invalidate() if you need to cancel the event before it ever happens.
Notes
If there is any chance of starting your timer instance multiple times, be sure that you invalidate the old timer instance first. Otherwise you lose the reference to the timer and you can't stop it anymore. (see this Q&A)
Don't use timers when they aren't needed. See the timers section of the Energy Efficiency Guide for iOS Apps.
Related
How to work with dates and time in Swift
Updated to Swift 4, leveraging 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)
}
}
As of iOS 10 there is also a new block based Timer factory method which is cleaner than using the selector:
_ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
label.isHidden = true
}
Swift 5
I personally prefer the Timer with the block closure:
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
// TODO: - whatever you want
}
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)
}
}
Notes
It needs to be on the main queue
Callback function can be public, private, ...
Callback function needs to be #objc
Check with:
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)
You will need to use Timer instead of NSTimer in Swift 3.
Here is an example:
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
}
First declare your timer
var timer: Timer?
Then add line in viewDidLoad() or in any function you want to start the timer
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(action), userInfo: nil, repeats: false)
This is the func you will callback it to do something it must be #objc
#objc func action () {
print("done")
}
for swift 3 and Xcode 8.2
(nice to have blocks, but if You compile for iOS9 AND want 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)
}
SimpleTimer (Swift 3.1)
Why?
This is a simple timer class in swift that enables you to:
Local scoped timer
Chainable
One liners
Use regular callbacks
Usage:
SimpleTimer(interval: 3,repeats: true){print("tick")}.start()//Ticks every 3 secs
Code:
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()
}
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)
And Create Fun By The Name createEnemy
fund createEnemy ()
{
do anything ////
}
In Swift 3 something like this with #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()
}
If you init method of timer
let timer = Timer(timeInterval: 3, target: self, selector: #selector(update(_:)), userInfo: [key : value], repeats: false)
func update(_ timer : Timer) {
}
then add it to loop using method other selector will not be called
RunLoop.main.add(timer!, forMode: .defaultRunLoopMode)
NOTE : If you are want this to repeat make repeats true and keep the reference of timer otherwise update method will not be called.
If you are using this method.
Timer.scheduledTimer(timeInterval: seconds, target: self, selector: #selector(update(_:)), userInfo: nil, repeats: true)
keep a reference for later use if repeats is true.
I tried to do in a NSObject Class and this worked for me:
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
print("Bang!") }
NSTimer has been renamed to Timer in Swift 4.2.
this syntax will work in 4.2:
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(UIMenuController.update), userInfo: nil, repeats: true)