Timers – believe me or not, but they are useful not only in programming stopwatches.
Let’s give some examples.
- To show a welcome screen and to close it after several seconds
- You are making a game and you would like to display an info how long user is playing current stage, without comparing NSDate (start and current).
- To create an animation without fade in / fade out effect.
Using timer (NSTimer) you are able to launch any task after given time or repeat it periodically.
Welcome screen
Welcome screen is shown only once during launch so there is no need to create any information in header file of your class about NSTimer. All you need to do is to add this line to your viewDidLoad method:
[NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(closeWelcomeScreen) userInfo:nil repeats:NO];
-(void)closeWelcomeScreen {
[welcomeScreen removeFromSuperview];
}
How long?
Now we will create a timer that will call the method every 0.01 second. In header file we need to add a float variable (float time;) and it’s also a label to show somewhere the value of this variable:
@interface MyView : UIViewController { IBOutlet UILabel *myLabel; float time; }
Now in viewDidLoad or any other method you will call by yourself, add:
[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(countTime) userInfo:nil repeats:YES];
And you need to implement countTime method:
-(void)countTime { time += 0.01; myLabel.text = [NSString stringWithFormat:@"%.2f",time]; }
As you see, this time NSTimer’s repeats property is set to YES, and that’s why it will call countTime method every 0.01 second.
Animations using NSTimer
As I told you before using typical animations (and transformations) ([UIView beginAnimations:nil context:NULL] and [UIView commitAnimations]) you get the nice fade in and out effect. To perform a rotation for example you have to create a similar timer like in code above, with tiny difference. It won’t be changing label’s text but transforming it using each time bigger angle.
[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(countTime) userInfo:nil repeats:YES]; -(void)countTime { rotation += 0.001; myLabel.transform = CGAffineTransformMakeRotation(M_PI*rotation); }
Remember to add in your header file rotation variable: float rotation;
Stoping NSTimer
In each of above examples when NSTimer repeats itself you can’t stop it – the time will grow and/or your object will be rotated. To obtain it you have to add the NSTimer object to the header and later in implementation to use it’s invalidate method whenever/wherever you want to stop it. Below I show you an example of the timer that will make a full rotation of myLabel and invaliate itself.
Header:
@interface MyView : UIViewController { IBOutlet UILabel *myLabel; float rotation; NSTimer *rotationTimer; }
Starting the timer:
rotationTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(rotate) userInfo:nil repeats:YES];
-(void)rotate { if (rotation >= 2.0) { [rotationTimer invalidate]; return; } rotation += 0.001; myLabel.transform = CGAffineTransformMakeRotation(M_PI*rotation); }
Personal experience
Timers can be more complex than just counting a time or perform a simple task. If you use timer as a run loop of your game for example, be careful. If many methods can invalidate the timer you should check if it cannot be invalidated twice sometimes. It will crash your application. Although NSTimer has the boolean method isValid, once NSTimer is invalidated you can’t use this property. Declaring any NSTimer I also add the boolean variable with similar name:
NSTimer *myTimer; bool myTimerInvalidated;
Each time I start the timer I set the boolean equals NO, each time I want to invalidate the timer I use:
if (!myTimerInvalidated) {
myTimerInvalidated = YES;
[myTimer invalidate];
}
Download the sample project to see live example of NSTimers.

Can you explain why I am having some strange behavior? I created a timer in my view controller via a startTimer button. I then clicked on a button that takes me to another view and when I return, my label that displays my count does not show anymore, but if I set breakpoints, the callback routine that updates my label is still being called. Any advice would greatly be appreciated. Thanks in advance.
Post some code plz.
Are you sure you are changing the label text property?
For example:
myLbl.text = [NSString stringWithFormat:@"%i",couter];
Is the other view created by different view controller or all views are handled by one viewController?
Regards
Chris
Very cool sample project.
THX