Paul masters
Paul masters

Reputation: 33

Using A NSTimer for MM:SS:HS?

I have created a NSTimer In Xcode 4.2 and it works but i get this one problem.

here is my project in the simulator

simulator

when i press start it starts and when i press stop it stops and when its stopped it will reset but when it starts and i press reset when it is going nothing happens it don't reset when started basically you have to stop then reset is the ways and this or do i need to add code any where heres a copy of my code.

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController {

    IBOutlet UILabel *time; 

    NSTimer *myticker;

    //declare baseDate
    NSDate* baseDate; 

}

-(IBAction)stop;
-(IBAction)reset;

@end

heres my implementation

 #import "FirstViewController.h"

@implementation FirstViewController

@synthesize baseDate;


-(IBAction)start {
    [myticker invalidate];
    self.baseDate = [NSDate date];
    myticker = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(showActivity) userInfo:nil repeats:YES];
}

-(IBAction)stop;{ 

    [myticker invalidate];
    myticker = nil;

}



-(IBAction)reset {
    self.baseDate = [NSDate date];
     time.text = @"00:00:0";  
}


-(void)showActivity {
    NSTimeInterval interval = [baseDate timeIntervalSinceNow];
    double intpart;
    double fractional = modf(interval, &intpart);
    NSUInteger hundredth = ABS((int)(fractional*10));
    NSUInteger seconds = ABS((int)interval);
    NSUInteger minutes = seconds/60;

    time.text = [NSString stringWithFormat:@"%02d:%02d:%01d", minutes%60, seconds%60, hundredth];
}

I Really Appreciate It. Thanks.

Upvotes: 0

Views: 1268

Answers (1)

user467105
user467105

Reputation:

First, the above should crash with EXC_BAD_ACCESS when it reaches showActivity since baseDate is not being retained in the start method. [NSDate date] returns an autoreleased object so baseDate will have an invalid reference after the start method.

I suggest changing baseDate to a retain property and then setting it in start using self.:

//.h
@property (nonatomic, retain) NSDate *baseDate;

//.m
@synthesize baseDate;

-(IBAction)start {
    [myticker invalidate];
    self.baseDate = [NSDate date];
    myticker = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(showActivity) userInfo:nil repeats:YES];
}


To fix the reset problem, note that the showActivity method takes the current value of baseDate to calculate the elapsed time and then sets the time label to display it formatted.

In the start method, you set the baseDate to the current time (you don't set time.text) and then start the timer. The showActivity method will then keep firing and set time.text.

In the reset method, you want the timer to start showing the elapsed time since the moment reset is pressed. The timer is already running so you don't need to re-start it. Setting the time label text doesn't work because when the already-running timer fires again, it will calculate the elapsed time from baseDate which is still the original start time and then set time.text based on that. So instead of setting time.text, set the baseDate:

-(IBAction)reset {
    self.baseDate = [NSDate date];
}

Upvotes: 2

Related Questions