Delaying Function in Swift

Delaying function in swift

You can use GCD (in the example with a 10 second delay):

Swift 2

let triggerTime = (Int64(NSEC_PER_SEC) * 10)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, triggerTime), dispatch_get_main_queue(), { () -> Void in
self.functionToCall()
})

Swift 3 and Swift 4

DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: {
self.functionToCall()
})

Swift 5 or Later

 DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
//call any function
}

How to create a delay in Swift?

Instead of a sleep, which will lock up your program if called from the UI thread, consider using NSTimer or a dispatch timer.

But, if you really need a delay in the current thread:

do {
sleep(4)
}

This uses the sleep function from UNIX.

How to program a delay in Swift 3

After a lot of research, I finally figured this one out.

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
// Code you want to be delayed
}

This creates the desired "wait" effect in Swift 3 and Swift 4.

Inspired by a part of this answer.

How can I call a function after a time delay in the main thread in Swift 3?

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

Is there a way to delay a return-Statement in Swift?

You are looking for a closure, a.k.a. completion handler.

return executes immediately and there is no way to delay that. Instead, you can use completion handlers, which work by passing in a closure as a parameter. This closure can then be called after a delay.

                            /// closure here!
func returnLate(completion: @escaping ((String) -> Void)) {
var string = "Wrong"
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
string = "right"
completion(string) /// similar to `return string`
}
}

override func viewDidLoad() {
super.viewDidLoad()
returnLate { string in
print("String is \(string)") /// String is right
}
}

Trouble delaying function with variables passed to it in swift 4

The problem is that attemptToIdentify(user) is a call. This is not the place for a call; you need a selector, i.e. the name of a function. So just put attemptToIdentify. If you need to pass something, you can pass it in the with parameter.

Even better, don't use perform:afterDelay: at all. If the idea is to add a delay to a call, just use asyncAfter (or my delay encapsulation of it).

How to delay the return to the calling function swift

Others have told you what to do, but not why.

You need to adjust your thinking.

With an event-driven device like an iPhone/iPad, you can't stop processing on the main thread for 5 seconds. The UI would lock up, and after a couple of seconds the system would kill your app as being hung.

Instead, what you do is to invoke a block of code (a closure) after a delay.

You could rewrite your function like this:

@IBAction func pickMeUpButton(sender: AnyObject) 
{
sendPushNotificationController().sendPushNotification("sendRequest",
userInfo: defaults.stringForKey("x73")!,
userInf23: defaults.stringForKey("x23")! )

initManager()

//Start the activity indicator during the delay
activityIndicator.center = self.view.center
self.view.addSubview(activityIndicator)
activityIndicator.startAnimating()

dispatch_after(
dispatch_time(DISPATCH_TIME_NOW, Int64(5.0 * Double(NSEC_PER_SEC))),
dispatch_get_main_queue())
{
//The code in the braces gets run after the delay value
locationManager.stopUpdatingLocation()
activityIndicator.stopAnimating()
}
//dispatch_after returns immediately, so code here will run before
//the delay period passes.
}

That button action code will:

Call initManager to start the location manager running.

Immediately create an activity indicator, add it to the view controller's content view, and start it spinning.

Then, the call to dispatch_after will wait for 5 seconds before running the code in the braces, which will stop the location manger and stop the activity indicator.

Delay code in a function that is called multiple times per second

To do so declare a global timer:

var timer: Timer = Timer(timeInterval: -1, target: self, selector: #selector(ViewControllerName.doStuff), userInfo: nil, repeats: false)

Where ViewControllerName is the name of the class that has doStuff() as a method.

Make sure to invalidate the timer initially (like in viewDidLoad()) :

timer.invalidate()

And here is how your doStuff() might look like:

func doStuff() {
//As long as the timer is started/vlaid, nothing will be executed
if !timer.isValid {
//print something or do whatever you'd like
print("some thing ", Date())

//and finally restart the timer
timer = Timer.scheduledTimer(
timeInterval: 1, //This is the time interval you don't want to do nothing
target: self,
selector: #selector(ViewController.doStuff),
userInfo: nil,
repeats: false)
}
}


Related Topics



Leave a reply



Submit