I have a DispatchQueue for a introViewController that shows a gif for 11 seconds and then display my login page... But also have a button that skip the intro and display the login. When I click it the time still running and when I am navigating in the app goes back to the login when the time ends.
this is my class
class GifClass: UIViewController {
@IBOutlet weak var gifImage: UIImageView!
@IBOutlet weak var skipButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
gifImage.loadGif(name: "promed")
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(11)) {
self.performSegue(withIdentifier: "introLogin", sender: self)
}
}
@IBAction func skip(_ sender: Any) {
performSegue(withIdentifier: "introLogin", sender: self)
}
}
how do I do to stop the time when I click the button?
You don't stop the queue. Instead, when the task that you dispatched starts executing, it needs to check its context and do the right thing (often: nothing) if the context has changed.
You can't pause / cancel when using a GCD queue. If you need that functionality (and in a lot of general cases even if you don't) you should be using the higher level API - NSOperationQueue .
A dispatch work item has a cancel flag. If it is cancelled before running, the dispatch queue won't execute it and will skip it. If it is cancelled during its execution, the cancel property return True. In that case, we can abort the execution.
Dispatch queues are FIFO queues to which your application can submit tasks in the form of block objects. Dispatch queues execute tasks either serially or concurrently. Work submitted to dispatch queues executes on a pool of threads managed by the system.
For this, you can use a DispatchWorkItem
. Here is the reference:
https://developer.apple.com/documentation/dispatch/dispatchworkitem
And here is an example of how you could use it in your code:
class GifClass: UIViewController {
@IBOutlet weak var gifImage: UIImageView!
@IBOutlet weak var skipButton: UIButton!
private var workItem: DispatchWorkItem? // Create a private DispatchWorkItem property
override func viewDidLoad() {
super.viewDidLoad()
gifImage.loadGif(name: "promed")
workItem = DispatchWorkItem { // Set the work item with the block you want to execute
self.performSegue(withIdentifier: "introLogin", sender: self)
}
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(11), execute: workItem!)
}
@IBAction func skip(_ sender: Any) {
workItem?.cancel() // Cancel the work item in the queue so it doesn't run
performSegue(withIdentifier: "introLogin", sender: self)
}
}
I'm not sure if there are best practices here, but I would consider doing what you are doing with a Timer rather than the DispatchQueue.
class GifClass: UIViewController {
@IBOutlet weak var gifImage: UIImageView!
@IBOutlet weak var skipButton: UIButton!
var timer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
gifImage.loadGif(name: "promed")
timer = Timer.scheduledTimer(timeInterval: 11, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)
}
@objc func timerAction() {
performSegue(withIdentifier: "introLogin", sender: self)
}
@IBAction func skip(_ sender: Any) {
timer.invalidate()
performSegue(withIdentifier: "introLogin", sender: self)
}
}
You don't stop the queue. Instead, when the task that you dispatched starts executing, it needs to check its context and do the right thing (often: nothing) if the context has changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With