Tuesday, January 22, 2013

Timer Countdown in iPhone Tutorial

Hola,, iCoder,, RDC is here

What's up guys, today we are going to learn one simple but important concept in iPhone application development.. Time Countdown using NSTime Class.

At the end of this Tutorial you can find Complete Source code zip file.

So stay with me, and do it step by step by .. don't forget to drop me a message or comment.



Note : This Application Developed Using : iOS 6. , Xcode 4.6, and MAC OS X Lion 10.8.3

PHASE - I (Create New Project)

So, Let's Fire Xcode!!

Go to File --> New --> Project

Now we can see a Pop up Window for selecting our application templet 

So make sure you select Application in iOS option on your Left hand side.
then select Single View Application as shown in below picture and Go for Next..



In the Next Window we need to put Our Project Details this way

 --------------------------------------------------------------
| Product Name : TimerDemo |
| Organization Name :RDCWorld |
| Company Identifier : com.rdcworld           |
| |
| Class Prefix :  (leave it blank for now) |
| |
| Devices : iPhone |
 --------------------------------------------------------------

Note : Don't forget to Make Tick mark on "Use Automatic Reference Counting" option.



Go to Next --> Create.

Now you can see Xcode default dashboard with our newly created project .

PHASE - II (Design UI)

We need to add one UITextField, and few UIButtons on our screen to get it work.

So, Just open ViewController.xib file you can see default blank layout

1. Let's drag UINavigationBar from Object library double click on it and give title as  "Countdown Timer", (we will use this for just showing app Title)

2.  Select main view and change background to Purple Colour or what you like or leave it as default.

3. Drag one UILabel from Object Lib and update its text => Timer Status , and expand its width as shown in screen shot.

4. now add Three UIButtons, give them names as Start, Pause,and Reset.

see below screen shot.



PHASE - III (Create IBOutlet and IBActions)

We are going to create IBOutlet for UITextField,UILabel and IBAction method for UIButton.

Okay, Now select Assistant Editor on Top Right side



You can see our ViewController.xib (Left side) + ViewController.h (Right side) opened together.

1. Fist is First, Create IBOutlet for UITextField,UILabel

Hold Ctrl button--> Select UILabel named "Timer Status" --> drag cursor to ViewController.h(right side) file, when your cursor is between @interface and @end.

while leaving cursor here you will get Popup Window 

just put Name : "timerLabel" and click on Connect.



now you can see below code line in your ViewController.h file (in right side)

@property (weak, nonatomic) IBOutlet UILabel *timerLabel;

do the same for UITextField, and UIButtons (one by one) give the name "timerValueTextField", "startButton", "pauseButton" and "resetButton" respectively.

after adding IBOutlet for all you can see IBOutlet property added to your header file.

@property (weak, nonatomic) IBOutlet UITextField *timerValueTextField;
@property (weak, nonatomic) IBOutlet UIButton *startButton;
@property (weak, nonatomic) IBOutlet UIButton *pauseButton;
@property (weak, nonatomic) IBOutlet UIButton *resetButton;


2. Create IBAction methods
2.1 Select UIButton (which says -'Start') --> Right Click on it 

2.2 Click on Touchup Inside in  "Sent Events" option and drag cursor just below to new created IBOutlets, and put the method name "startTimer" in pop window



you can see IBAction method added in header file 

- (IBAction)startTimer:(id)sender;

2.3 do the same for next two Buttons and give methods name as "stopTimer", and "resetTimer" respectively.

this time you can see three new  IBAction methods created in header file

- (IBAction)stopTimer:(id)sender;
- (IBAction)resetTimer:(id)sender;


Done!! now back to Standard Editor



PHASE - IV (Writing Code)

~ ~ ~ ~ ~ ~ ~ ~ ~              Controller Class (ViewController)          ~ ~ ~ ~ ~ ~ ~ ~ ~  


1. open ViewController.h

2. declare an integer for Timer Value

int secondsLeft;

3.  create NSTimer instance with property

@property (nonatomic, weak) NSTimer *timer;

4. just before @end add one IBAction method to handle keypad go

- (IBAction)keypadGoBack:(id)sender;

So Finally our ViewController.h file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.h
//  TimerDemo
//
//  Created by RDC on 22/01/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController{
    int secondsLeft;
}
@property (nonatomic, weak) NSTimer *timer;

@property (weak, nonatomic) IBOutlet UILabel *timerLabel;
@property (weak, nonatomic) IBOutlet UITextField *timerValueTextField;
@property (weak, nonatomic) IBOutlet UIButton *startButton;
@property (weak, nonatomic) IBOutlet UIButton *pauseButton;
@property (weak, nonatomic) IBOutlet UIButton *resetButton;

- (IBAction)startTimer:(id)sender;
- (IBAction)stopTimer:(id)sender;
- (IBAction)resetTimer:(id)sender;
- (IBAction)keypadGoBack:(id)sender;
@end
-----------------------------------------------------------------------------------------------------------------------------------------

Now come to ViewController.m file , open it

Here is the Heart of Application

1. To create Timer Countdown, we need to create NSTime class object with some properties like Time interval and the selector  method so we can handle any action with Timer.

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runScheduledTask:) userInfo:nil repeats:YES];

 Here we have 1 second time interval, and selector method name "runScheduledTask"

2. also we need to provide body for selector method

- (void)runScheduledTask: (NSTimer *) runningTimer {    
    int hours, minutes, seconds;
    secondsLeft--;
    hours = secondsLeft / 3600;
    minutes = (secondsLeft % 3600) / 60;
    seconds = (secondsLeft %3600) % 60;    
    timerLabel.text =[NSString stringWithFormat:@"Time Remaining %02d:%02d:%02d", hours, minutes, seconds];    
    if (secondsLeft==0) {        
        [timer invalidate];        
        timerLabel.text = @"Time up!!";        
    }
}

3. we can stop Timer using Invalidate 

[timer invalidate];


So Finally our ViewController.m file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.m
//  TimerDemo
//
//  Created by RDC on 22/01/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

@synthesize timer;
@synthesize timerValueTextField;
@synthesize timerLabel;
@synthesize pauseButton;
@synthesize startButton;
@synthesize resetButton;

- (void)viewDidLoad{
    [super viewDidLoad];
    [pauseButton setEnabled:NO];
    [resetButton setEnabled:NO];    
}

- (void)didReceiveMemoryWarning{
    [super didReceiveMemoryWarning];    
}

- (void)runScheduledTask: (NSTimer *) runningTimer {    
    int hours, minutes, seconds;
    secondsLeft--;
    hours = secondsLeft / 3600;
    minutes = (secondsLeft % 3600) / 60;
    seconds = (secondsLeft %3600) % 60;    
    timerLabel.text =[NSString stringWithFormat:@"Time Remaining %02d:%02d:%02d", hours, minutes, seconds];    
    if (secondsLeft==0) {        
        [timer invalidate];        
        timerLabel.text = @"Time up!!";        
    }
}

- (IBAction)startTimer:(id)sender {
    [pauseButton setTitle:@"Pause" forState:UIControlStateNormal];    
    secondsLeft = [timerValueTextField.text intValue];    
    // This will allow 10,000 Hours Timer Limits
     if (secondsLeft >0 && secondsLeft <36000001 ) {        
        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runScheduledTask:) userInfo:nil repeats:YES];
        [startButton setEnabled:NO];
        [pauseButton setEnabled:YES];
        [resetButton setEnabled:YES];
    }
    else{                
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Please! enter valid timer value" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        [alert show];       
    }
}

- (IBAction)stopTimer:(id)sender {    
    if ([@"Pause" isEqualToString:[pauseButton titleForState:UIControlStateNormal]]) {
        NSLog(@"Paused");
        [pauseButton setTitle:@"Resume" forState:UIControlStateNormal];        
        [startButton setEnabled:NO];
        [pauseButton setEnabled:YES];
        [resetButton setEnabled:NO];        
        if (timer != nil) {
            [timer invalidate];            
            int hours, minutes, seconds;
            hours = secondsLeft / 3600;
            minutes = (secondsLeft % 3600) / 60;
            seconds = (secondsLeft %3600) % 60;            
            timerLabel.text =[NSString stringWithFormat:@"Time paused at %02d:%02d:%02d", hours, minutes, seconds];           
        }        
    }
    else{
        NSLog(@"Resumed");
        [pauseButton setTitle:@"Pause" forState:UIControlStateNormal];
        [startButton setEnabled:NO];
        [pauseButton setEnabled:YES];
        [resetButton setEnabled:YES];        
        timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runScheduledTask:) userInfo:nil repeats:YES];        
        if (secondsLeft==0) {            
            NSLog(@"Time up!!");            
            [timer invalidate];
            timerLabel.text = @"Time up!!";            
        }
    }    
}

- (IBAction)resetTimer:(id)sender {
    [startButton setEnabled:YES];
    [pauseButton setEnabled:NO];
    [resetButton setEnabled:NO];    
    [pauseButton setTitle:@"Pause" forState:UIControlStateNormal];
    if (timer != nil) {
        [timer invalidate];
        timerLabel.text = @"Timer got reset!!";
    }else{
        NSLog(@"timer is nil");
    }    
    timerValueTextField.text=@"";    
}

-(IBAction)keypadGoBack:(id)sender{
    [timerValueTextField resignFirstResponder];
}
@end
-----------------------------------------------------------------------------------------------------------------------------------------

~ ~ ~ ~ ~ ~ ~ ~ ~              Application Delegate Class (AppDelegate)          ~ ~ ~ ~ ~ ~ ~ ~ ~  


Make sure your AppDelegate file code should be default 

Finally our AppDelegate.h file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.h
//  TimerDemo
//
//  Created by KNSMac2 on 22/01/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *viewController;

@end
-----------------------------------------------------------------------------------------------------------------------------------------


Finally our AppDelegate.m file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.m
//  TimerDemo
//
//  Created by RDC on 22/01/13.
//  Copyright (c) 2013 RDC World. All rights reserved.
//

#import "AppDelegate.h"
#import "ViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];    
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

//for now leave rest all empty methods..
@end
-----------------------------------------------------------------------------------------------------------------------------------------

Okay wrap it up this application. let's Run it.
we can Start, Pause, Resume and Stop Timer..



Cheers!! we did it. 

You can find complete project source code zip file here : TimerDemo.zip (67.22 KB)


I Would love to here your thoughts !! 

No comments:

Post a Comment