This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to Pause/Play NSTimer?
I have three buttons start stop and pause..My start and stop button is working fine with the below code..but when press Pause it pause the timer..but when again i Press start.IT continues from the new added time ...not from the pause time....
supoose i pause at 5 second of start and wait for 5 sec then press start...it should display 5 ...but displaying 10..
because I have not mentioned (timer:) in timer!=nill of start...
how it will be add..
I have problems:
Pause not working.
-(void)start:(NSTimer *)timer
{
if(_timer==nil)
{
startDate =[NSDate date];
_timer=[NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:#selector(timer:) userInfo:nil repeats:YES];
}
if(_timer!=nil)
{
float pauseTime = -1*[pauseStart timeIntervalSinceNow];
[_timer setFireDate:[previousFireDate initWithTimeInterval:pauseTime sinceDate:previousFireDate]];
}
}
-(void)timer:(NSTimer *)timer
{
NSInteger secondsSinceStart = (NSInteger)[[NSDate date] timeIntervalSinceDate:startDate];
NSInteger seconds = secondsSinceStart % 60;
NSInteger minutes = (secondsSinceStart / 60) % 60;
NSInteger hours = secondsSinceStart / (60 * 60);
NSString *result = nil;
if (hours > 0)
{
result = [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes, seconds];
}
else
{
result = [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
}
label.text=result;
NSLog(#"time interval -> %#",result);
}
-(void)stop
{
if(_timer!=nil)
{
startDate=nil;
[_timer invalidate];
_timer = nil;
}
}
-(void)pause:(NSTimer *)timer
{
pauseStart = [NSDate dateWithTimeIntervalSinceNow:0];
previousFireDate = [_timer fireDate];
[_timer setFireDate:[NSDate distantFuture]];
}
-(void)pause:(NSTimer *)timer
{
pauseStart = [NSDate dateWithTimeIntervalSinceNow:0];
previousFireDate = [_timer fireDate];
//[timer setFireDate:[NSDate distantFuture]];
[_timer setFireDate:[NSDate distantFuture]];
}
Here is the code that I used for a timer:
I store all the components for the time, in my (singleton) class, the hour, minute, seconds value.
And, I simply "invalidate" the timer in the "pause" method, AND I store the values.
See, if this helps.
-(void) startTimer
{
NSLog(#"Values for timer: %d H, %d M, %d S", self.hours, self.minutes, self.seconds);
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateTimer) userInfo:nil repeats:YES];
}
-(void) pauseTimer
{
if(_timer)
{
[_timer invalidate];
}
_timer = nil;
self.hour = hourValue;
self.minute = minuteValue;
self.second = secondsValue;
}
Related
I m using timer on circular progress bar and taken NSDate property in interface (tested also taking in viewWillAppear) but when viewController loads it show starting from 27 seconds remain, while i have set its value to 30 seconds.
My scenario is, a user has a question and optional answers and he/she has some time suppose 30 seconds when he/she click start button than another screen opens after this screen loads time start should be from 30 seconds.
#interface TestViewController ()
{
NSTimeInterval totalCountdownInterval;
NSDate* startDate;
}
}
-(void)viewWillAppear:(BOOL)animated{
[self startTimer];
totalCountdownInterval = 30.0;
startDate = [NSDate date];
}
-(void)startTimer {
if (!_timer) {
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:#selector(timerFired:)
userInfo:nil
repeats:YES];
}
}
-(void)stopTimer {
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
}
-(void)timerFired:(NSTimer *)timer {
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startDate];
NSTimeInterval remainingTime = totalCountdownInterval - elapsedTime;
CGFloat timeRemain = remainingTime;
NSLog(#"%f", timeRemain);
if (remainingTime < 0.0) {
[_timer invalidate];
}
[_circleProgressBar setHintTextGenerationBlock:(^NSString *(CGFloat progress) {
if (!(timeRemain < 0.9)) {
progress = timeRemain - 1;
return [NSString stringWithFormat:#"%.0f", progress];
}else{
progress = 0;
return [NSString stringWithFormat:#"%.0f", progress];
}
})];
[_circleProgressBar setProgress:(_circleProgressBar.progress + 0.0333f) animated:YES];
}
-(void) viewWillDisappear:(BOOL)animated {
[self stopTimer];
}
Any help will be appreciated. Thanks.
The first timer event will be fired after 1 second is passed, so you should see 29 first. So you should display the number 30 manually somehow, outside the timer event.
And you subtract 1 in your code in setHintTextGenerationBlock :
progress = timeRemain - 1;
which will make you see 28 as initial.
And as final you should start timer in viewDidAppear instead of viewWillAppear where you lose another second and come to 27.
To correct code should be like:
#interface TestViewController ()
{
NSTimeInterval totalCountdownInterval;
NSDate* startDate;
}
}
-(void)viewDidLoad {
[_circleProgressBar setHintTextGenerationBlock:(^NSString *(CGFloat progress) {
return [NSString stringWithFormat:#"%.0f", progress * 30];
})];
[_circleProgressBar setProgress:1.0) animated:NO];
}
-(void)viewDidAppear:(BOOL)animated{
[self startTimer];
totalCountdownInterval = 30.0;
startDate = [NSDate date];
}
-(void)startTimer {
if (!_timer) {
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:#selector(timerFired:)
userInfo:nil
repeats:YES];
}
}
-(void)stopTimer {
if ([_timer isValid]) {
[_timer invalidate];
}
_timer = nil;
}
-(void)timerFired:(NSTimer *)timer {
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startDate];
NSTimeInterval remainingTime = totalCountdownInterval - elapsedTime;
CGFloat timeRemain = remainingTime;
NSLog(#"%f", timeRemain);
if (remainingTime < 0.0) {
[_timer invalidate];
}
[_circleProgressBar setProgress:(1.0 * timeRemain / 30.0) animated:YES];
}
-(void) viewWillDisappear:(BOOL)animated {
[self stopTimer];
}
You should set progress to 1.0 in the beginning and count down to 0.0 in 30 steps.
Set hint generation block to display something meaningful for 1.0 - 0.0 as 30 - 0.
use that timer code in void view did appear and try once.
- (void)viewDidAppear:(BOOL)animated
{
[self startTimer];
totalCountdownInterval = 30.0;
startDate = [NSDate date];
}
i know how to start NSTimer and i given the code for this but now i want to stop the NSTimer after 3 or 4 minutes but how can i do this
i know how to give NSTimer but how to stop after 3 minutes
need some help
NSTimer* myTimer;
myTimer= [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self
selector: #selector(updateUIinMainThread:) userInfo: nil repeats: YES];
Declaration :
int totalSeconds;
NSTimer *twoMinTimer;
Code :
- (void)timer {
totalSeconds--;
if ( totalSeconds == 0 ) {
[twoMinTimer invalidate];
//Timer stops after 2 minute from this you can do your stuff here
}
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
totalSeconds = 120;
twoMinTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timer)
userInfo:nil
repeats:YES];
}
Hope this helps
Save the time when the timer is initiated
NSTimer* myTimer;
myTimer= [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self
selector: #selector(updateUIinMainThread:) userInfo: nil repeats: YES];
savedTime = [NSDate date];
and in function updateUIinMainThread: compare current time to saved time. If the result is greater than 180 seconds, stop the timer.
-(void)updateUIinMainThread:(NSTimer *)timer
{
NSDate *timeNow = [NSDate date];
NSTimeInterval timespan = [timeNow timeIntervalSinceDate:savedTime];
if(timesapn>180)
{
[timer invalidate];
}
}
May be the following code will help you:
step 1: declare following instance variables
#interface yourclass : NSObject
{
NSTimer* myTimer;
NSDate *initialDate;
}
step 2: create myTimer in your class where you want:
myTimer= [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(callByTimer) userInfo:nil repeats:YES];
step 3: implement callByTimer method:
- (void)callByTimer{
// get initial date at very first call by myTimer
if (!initialDate)
{
initialDate = [NSDate date];
}
// get current date
NSDate *currentDate = [NSDate date];
// get seconds between currentdate and initial date
NSTimeInterval secondsBetween = [currentDate timeIntervalSinceDate:initialDate];
// convert seconds into minutes
NSInteger minutes = secondsBetween/60;
// check if minutes is greater than or equal to 3 then invalidate myTimer and assign nil to initialDate variable
if (minutes>=3)
{
[myTimer invalidate];
initialDate = nil;
}}
I have 3 UIlabel
First UILabel show- hh(hours)
Second UILabel show- mm(minutes)
Third UILabel show- ss(seconds)
Time is already showing in UILabels , but it has to run or tick reversely.
Means- 10:04:45 will come to 00:00:00--
This is what i am trying.
#pragma mark - Timer Function
-(NSArray *)getTimeFromSring:(NSString *)time
{
//only accepting time format hh:mm:ss
NSMutableArray *resultArr=[[NSMutableArray alloc]init];
int count=1;
for(int i=0;i<[time length];i++)
{
unichar ch = [time characterAtIndex: i];
if(ch!=':' && count<=3)
{
NSString *appendString = [NSString stringWithFormat:#"%c",ch];
[resultArr addObject:appendString];
}
else
{
count++;
}
}
return resultArr;
}
Finally
-(void)start:(NSTimer *)timer
{
if(_timer==nil)
{
startDate =[NSDate date];
_timer=[NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:#selector(timer:) userInfo:nil repeats:YES];
}
if(_timer!=nil)
{
float pauseTime = -1*[pauseStart timeIntervalSinceNow];
[_timer setFireDate:[previousFireDate initWithTimeInterval:pauseTime sinceDate:previousFireDate]];
}
}
-(void)timer:(NSTimer *)timer
{
NSInteger secondsSinceStart = (NSInteger)[[NSDate date] timeIntervalSinceDate:startDate];
NSInteger seconds = secondsSinceStart % 60;
NSInteger minutes = (secondsSinceStart / 60) % 60;
NSInteger hours = secondsSinceStart / (60 * 60);
NSString *result = nil;
if (hours > 0)
{
result = [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes, seconds];
}
else
{
result = [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
}
label.text=result;
NSLog(#"time interval -> %#",result);
}
-(void)stop
{
if(_timer!=nil)
{
endDate = [NSDate date];
NSLog(#"endate%#",endDate);
NSTimeInterval interval = [endDate timeIntervalSinceDate:startDate];
NSLog(#"total time %f",interval);
[_timer invalidate];
_timer = nil;
startDate=nil;
}
}
A couple of possible approaches, depending on the specifics of what you want to do:
Keep track of the elapsed time and subtract it from the start time.
Calculate the end time at the start and figure out the difference between the current time and then.
Take a look at these examples, maybe they will help you:)
https://github.com/mineschan/MZTimerLabel
https://github.com/TriggerTrap/TTCounterLabel
I've been trying to create a script that sets a timer and reduces a value by 33 each time it runs. In theory the timer should stop itself after 6 runs, but it keeps going and reaches negative values. Is there a reason for this?
-(void)checkValue:(NSTimer *)myTimer{
if(pplint > 0){
pplint = pplint-33;
NSString *ppllefttext = [NSString stringWithFormat:#"%d", pplint];
peopleleft.text = ppllefttext;
NSLog(#"Reduced Timer");
}
if(pplint < 0){
NSLog(#"Stop Timer");
[myTimer invalidate];
}
}
- (IBAction)gotocongrats{
pplint = 198;
NSString *ppllefttext = [NSString stringWithFormat:#"%d", pplint];
peopleleft.text = ppllefttext;
NSTimer * myTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(checkValue:)
userInfo:nil
repeats:YES];
NSLog(#"Started Timer");
}
I took you code and edited it a bit and it works just fine for me.
-(void)checkValue:(NSTimer *)myTimer{
if(pplint > 0){
pplint = pplint-33;
NSLog(#"%i",pplint);
NSLog(#"Reduced Timer");
}
if(pplint <= 0){
NSLog(#"Stop Timer");
[myTimer invalidate];
}
}
- (IBAction)gotocongrats{
pplint = 198;
NSTimer * myTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(checkValue:)
userInfo:nil
repeats:YES];
NSLog(#"Started Timer");
}
I am using NSTimer to make a stopwatch. I would like it to continue working if the user switches to a different app, but right now it only works when the app is running. I figure that this is probably pretty simple to fix by recording a timestamp when the timer starts, but I'm not really sure how to reconcile that with the ability to pause/restart the timer in the middle.
My code:
-(IBAction)start;
{
if(sharedInstance.timer == nil){
sharedInstance.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(showActivity) userInfo:nil repeats:YES];
sharedInstance.timerRunning = YES;
}
}
-(IBAction)stop;
{
[sharedInstance.timer invalidate];
sharedInstance.timer = nil;
sharedInstance.timerRunning = NO;
}
-(void)showActivity;
{
sharedInstance.elapsedTime += 1;
int hours = sharedInstance.elapsedTime / 3600 ;
int minutes = sharedInstance.elapsedTime / 60 - hours * 60;
int seconds = sharedInstance.elapsedTime - hours * 3600 - minutes * 60;
sharedInstance.timeString = [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes, seconds];
self.readout.text = sharedInstance.timeString;
}
-(void)viewDidLoad {
sharedInstance = [DataSingleton sharedInstance];
if (sharedInstance.timeString==nil) {
sharedInstance.timeString=#"00:00:00";
}
self.readout.text = sharedInstance.timeString;
[sharedInstance.timer invalidate];
sharedInstance.timer = nil;
if(sharedInstance.timerRunning) {
[self start];
}
[super viewDidLoad];
}
-(void)reset {
[self stop];
sharedInstance.elapsedTime = 0;
sharedInstance.timeString = #"00:00:00";
self.readout.text = sharedInstance.timeString;
}
Every time you call showActivity you could get a new time stamp and subtract the old one from it getting the change in time. Then add that to elapsedTime instead of 1.