swift invalidate timer doesn't work
The usual way to start and stop a timer safely is
var timer : Timer?
func startTimer()
{
if timer == nil {
timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
}
}
func stopTimer()
{
timer?.invalidate()
timer = nil
}
startTimer()
starts the timer only if it's nil
and stopTimer()
stops it only if it's not nil
.
You have only to take care of stopping the timer before creating/starting a new one.
Timer does not invalidate
You might be starting multiple timers. If you hit the line of code that creates a timer before the current one has been invalidated, then you will have two active timers, only one of which you can invalidate.
To prevent this possibility, call invalidate
on scoreTimer
before creating a new timer:
scoreTimer.invalidate()
scoreTimer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(updatePassengerScore), userInfo: nil, repeats: true)
The other way to handle it is to change scoreTimer
to an optional, and then only create a timer if scoreTimer
is nil
.
var scoreTimer: Timer?
...
if scoreTimer == nil {
scoreTimer = Timer.scheduledTimer(...
}
...
scoreTimer?.invalidate()
scoreTimer = nil
Swift timer won't work after invalidating and reinitiating
The reason was that the timer starts executing in other thread, not in main thread.
Timer will not Invalidate swift 4
Your problem lies in this part of your code.
Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(timeoutPeriod)), userInfo: nil, repeats: true)
You're creating a Timer but not setting it into the Timer
variable you created var timer = Timer()
To fix this you just have to set your Timer
variable correctly.
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(timeoutPeriod)), userInfo: nil, repeats: true)
Timer keeps working after invalidate() and nil
You are almost certainly assigning precentageTimer
twice without invalidating it in between. This is a very common mistake. The function that includes self.precentageTimer =
is probably being called multiple times before viewWillDisappear
is called. Since you tied it to a button press, it's likely happening if the button is pressed twice.
The usual solution is to add a willSet
to percentageTimer
like this (and you do not want percentageTimer
to be !
; it absolutely should be ?
because it can be legitimately nil):
var precentageTimer: Timer? {
willSet {
percentageTimer?.invalidate()
}
}
Timer doesn't stop on swift
you are creating another instance of timer inside FireTimer()
function with same name, just remove and try
Swift - Timer doesn't stop
After research I found a solution,
The only thing that worked for me is to create functions in AppDelegate file and call them when needed,
Here is the code, the timerSwitch function:
func timerSwitch()
{
if (timerStatus) {
checkStateTimer = Timer.scheduledTimer(
timeInterval: 60,
target:self,
selector: #selector(self.yourFunction),
userInfo: nil, repeats: true)
} else {
checkStateTimer?.invalidate()
}
}
func stopTimer()
{
timerStatus = false
timerSwitch()
}
func startTimer()
{
timerStatus = true
timerSwitch()
}
While 'yourFunction' is what you want to execute when the timer starts,
In my case is sending heartbeat.
Then I called the timerSwitch is the following functions in AppDelegate:
func applicationWillResignActive(_ application: UIApplication) {
stopTimer()
}
func applicationDidEnterBackground(_ application: UIApplication) {
stopTimer()
}
func applicationDidBecomeActive(_ application: UIApplication) {
startTimer()
}
Swift | The timer wont stop on invalidate call, rather speeds up?
As far as I can recognize, you have 2 mistakes.
First one is mentioned by the other answer. It is a true suggestion that you shouldn't always add a new UIButton and should use just hide/unhide property for each button.
Second mistake is on how you add a target. You are using .allTouchEvents, however you might intent to use .touchUpInside as your control state.
Kindly see the below corrected code for your reference:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var titleLabel: UILabel!
var startButton: UIButton!
var stopButton: UIButton!
var timer: Timer!
var counter: Double = 0.0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
startButton = UIButton(frame: CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1))
startButton.setTitle("Start Timer", for: .normal)
startButton.setTitleColor(.white , for: .normal)
startButton.backgroundColor = .red
startButton.addTarget(self, action: #selector(playButton(_:)), for: .touchUpInside)
self.view.addSubview(startButton)
self.startButton.isHidden = false
stopButton = UIButton(frame: CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1))
stopButton.setTitle("Stop Timer", for: .normal)
stopButton.setTitleColor(.white , for: .normal)
stopButton.backgroundColor = .red
stopButton.addTarget(self, action: #selector(pauseButton(_:)), for: .touchUpInside)
self.view.addSubview(stopButton)
self.stopButton.isHidden = true
}
@objc func playButton(_ sender : Any) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true)
startButton.isEnabled = false
stopButton.isEnabled = true
startButton.isHidden = true
stopButton.isHidden = false
}
@objc func pauseButton(_ sender: Any) {
timer.invalidate()
stopButton.isHidden = true
startButton.isHidden = false
startButton.isEnabled = true
stopButton.isEnabled = false
}
@objc func updateTimer(_ sender : Any)
{
counter += 0.1
titleLabel.text = String(format: "%.1f", counter)
}
}
Related Topics
Detect App Launch from Widgetkit Widget Extension
Prevent Dispatch_After() Background Task from Being Executed
How to Disable 4 Finger Gestures on iPad
Responding to Ram Availability in iOS
Objective-C Wrapper for Cfunctionpointer to a Swift Closure
Nsgenericexception Reason Collection <Nsconcretemaptable: Xxx>
Uiimagejpegrepresentation Received Memory Warning
Get User Profile Details (Especially Email Address) from Twitter in iOS
iOS Facebook Sdk - Post Open Graph and Show on Timeline Without Clicking Activity Log
What Is the Swift Equivalent of Makeobjectsperformselector
Setting Image for Uibarbuttonitem - Image Stretched
iOS 10, Nsuserdefaults Does Not Work
Can Somebody Give a Snippet of "Append If Not Exists" Method in Swift Array
Marking Some Xib/Storyboard Strings as Not Localizable