Reputation: 1288
I have a UIControl that calls a function after 0.5 seconds depending on how many times the user presses it. (Eg 1 press calls f1(), 2 presses calls f2(), 3 presses calls f3())
So basically I need to set a timer when a user presses the Control. If the Control is not pressed for 0.5 seconds then create a dialog. I have tried using a DispatchQueue, but when it gets to the point of making the dialog, it takes several seconds. I think it is because it is being called concurrently instead of on the main thread (apologies if poor terminology).
self.operationQueue.cancelAllOperations() //To cancel previous queues
self.mainAsyncQueue = DispatchQueue(label: "bubblePressed" + String(describing: DispatchTime.now()), qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent)
let time = DispatchTime.now()
self.currentTime = time
self.mainAsyncQueue!.asyncAfter(deadline: time + 0.5){
guard self.currentTime == time else {
return
}
let tempOperation = BlockOperation(block:{
self.displayDialog()
})
self.operationQueue.addOperation(tempOperation)
}
operationQueue
and mainAsycQueue
are defined in viewDidLoad
as
self.currentTime = DispatchTime.now()
self.operationQueue = OperationQueue()
How can I call my function displayDialog()
in the main thread so that it loads faster?
Upvotes: 2
Views: 9685
Reputation: 114836
I don't think it needs to be anywhere near that complicated. You can just use a Timer
;
class MyClass: UIViewController {
var tapCount = 0
var tapTimer: Timer?
@IBAction tapped(_ sender: Any) {
if tapCount < 3 {
tapCount += 1
tapTimer?.invalidate()
tapTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: { (timer) in
switch (self.tapCount) {
case 1:
self.f1()
case 2:
self.f2()
case 3:
self.f3()
default:
// Hmm, shouldn't happen
}
self.tapCount = 0
})
}
}
The timer will be scheduled on the main queue by default, so there is no need to dispatch anything on the main queue specifically
Upvotes: 3
Reputation: 2092
Based on the question title, answer is:
let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
//update UI here
self.displayDialog()
}
or
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.displayDialog()
}
Upvotes: 5
Reputation: 9503
Use below func, it executes the func in the main thread and no other action will perform during this execution.
DispatchQueue.main.async {
self.displayDialog()
}
Upvotes: 0