Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Wait in Objective-C and Swift

I want to change my UILabel's text after 2 seconds.

I tried setting my UILabel's text to "A text", and use sleep(2) and finally changing the text to "Another text".

But sleep(2) only freezes the app and "Another text" is set without displaying "A text" for 2 seconds.

How may I display "A text" for 2 seconds and then show "Another text"?

like image 306
jylee Avatar asked Aug 08 '11 14:08

jylee


People also ask

How do you wait in Objective-C?

You can use : NSThread sleepForTimeInterval:2.0f]; to delay the thread for 2 seconds. I think the NSTimer is a great solution.

How to call a method with delay in Swift?

Execute Code After Delay Using asyncAfter() Sometimes, you might hit the requirement to perform some code execution after a delay, and you can do this by using Swift GCD (Grand Central Dispatch) system to execute some code after a set delay.

How can Swift and Objective-C be used in the same project?

To access and use swift classes or libraries in objective-c files start with an objective-c project that already contains some files. Add a new Swift file to the project. In the menu select File>New>File… then select Swift File, instead of Cocoa Touch Class. Name the file and hit create.

Does Apple use Swift or Objective-C?

Apple's Calculator application, for example, is mostly powered by Swift. With less than 3% of its classes written in Swift, the WWDC application is primarily built on C and Objective-C.


3 Answers

I know I am late to this party. But I found people haven't mention thread sleep. If you are using GCD to call that function. You can use :

NSThread sleepForTimeInterval:2.0f];   

to delay the thread for 2 seconds.

[self changeText: @"A text"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  //Here your non-main thread.
  [NSThread sleepForTimeInterval:2.0f];   
  dispatch_async(dispatch_get_main_queue(), ^{
    //Here you returns to main thread.
    [self changeText: @"Another text"];
  });
});

Edit 2 (Feb 2015)

I think the NSTimer is a great solution. My solution just giving another option to achieve the goal of NSTimer.

Please read: How do I use NSTimer?

[NSTimer scheduledTimerWithTimeInterval:2.0
         target:self
         selector:@selector(doSomethingWhenTimeIsUp:)
         userInfo:nil
         repeats:NO];

In the class, you need this method:

- (void) doSomethingWhenTimeIsUp:(NSTimer*)t {
  // YES! Do something here!!
}

Edit 3 (May 2016)

In Swift 2.0, you can use this way:

NSTimer.scheduledTimerWithTimeInterval(2.0, 
                                       target: self, 
                                       selector: "doSomethingWhenTimeIsUp:", 
                                       userInfo: nil, 
                                       repeats: false)

It creates an NSTimer's entity and adds the timer automatically to the NSRunLoop associated with the NSThread in which the timer is created.

Edit 4 (Jun 2016) In Swift 2.2, the way to invoke select is:

#selector(doSomethingWhenTimeIsUp(_:))

So, it is something like:

NSTimer.scheduledTimerWithTimeInterval(2.0,
                                       target: self,
                                       selector: #selector(doSomethingWhenTimeIsUp()),
                                       userInfo: nil,
                                       repeats: false)

Edit 5 (Oct 2016)

In Swift 3, the way to invoke select is:

#selector(doSomethingWhenTimeIsUp)

So, it is something like:

Timer.scheduledTimer(timeInterval: 2.0,
                     target: self,
                     selector: #selector(doSomethingWhenTimeIsUp),
                     userInfo: nil,
                     repeats: false)

Then, the func should looks like this:

@objc private func doSomethingWhenTimeIsUp(){
  // Do something when time is up
}

Edit 6 (May 2018) In Swift 4, we can do as below way.

let delaySeconds = 2.0
DispatchQueue.main.asyncAfter(deadline: .now() + delaySeconds) {
  doSomethingWhenTimeIsUp()
}  

Then, the func should looks like this:

private func doSomethingWhenTimeIsUp(){
  // Do something when time is up
}
like image 73
Yi Jiang Avatar answered Oct 11 '22 10:10

Yi Jiang


You can use

[self performSelector:@selector(changeText:) withObject:text afterDelay:2.0];

or if you want to display it periodically, check the NSTimer class.

like image 42
Michał Zygar Avatar answered Oct 11 '22 12:10

Michał Zygar


Grand Central Dispatch has a helper function dispatch_after() for performing operations after a delay that can be quite helpful. You can specify the amount of time to wait before execution, and the dispatch_queue_t instance to run on. You can use dispatch_get_main_queue() to execute on the main (UI) thread.

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    // do something
});

In Swift 3, the above example can be written as:

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    // do something
}
like image 30
Mick MacCallum Avatar answered Oct 11 '22 12:10

Mick MacCallum