How do I pause a stopwatch, then have it pick back up from where it started? - objective-c

I am designing a timer that I want to be able to pause and continue from the same place. I tried doing it but the code wouldn't work for me. Here is my code:
.m file:
-(IBAction)buttonPause:(id)sender {
NSString *dateString = timer.text;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.SS"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
dateFromString = startDate;
}
- (IBAction)buttonStart:(id)sender {
startDate = [NSDate date];
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/100.0
target:self
selector:#selector(updateTimer)
userInfo:nil
repeats:YES];
}
- (void)updateTimer{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
timer.text = timeString;
}
My problem appears to lie in the buttonPause method. What am I doing wrong or am not doing? Thank you in advanced.

You can use NSTimeInterval instead of timer. I have a functional code to pause and stop the timer.
#interface PerformBenchmarksViewController () {
int currMinute;
int currSecond;
int currHour;
int mins;
NSDate *startDate;
NSTimeInterval secondsAlreadyRun;
}
#end
- (void)viewDidLoad
{
[super viewDidLoad];
running = false;
}
- (IBAction)StartTimer:(id)sender {
if(running == false) {
//start timer
running = true;
startDate = [[NSDate alloc] init];
startTime = [NSDate timeIntervalSinceReferenceDate];
[sender setTitle:#"Pause" forState:UIControlStateNormal];
[self updateTime];
}
else {
//pause timer
secondsAlreadyRun += [[NSDate date] timeIntervalSinceDate:startDate];
startDate = [[NSDate alloc] init];
[sender setTitle:#"Start" forState:UIControlStateNormal];
running = false;
}
}
- (void)updateTime {
if(running == false) return;
//calculate elapsed time
NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval elapsed = secondsAlreadyRun + currentTime - startTime;
// extract out the minutes, seconds, and hours of seconds from elapsed time:
int hours = (int)(mins / 60.0);
elapsed -= hours * 60;
mins = (int)(elapsed / 60.0);
elapsed -= mins * 60;
int secs = (int) (elapsed);
//update our lable using the format of 00:00:00
timerLabel.text = [NSString stringWithFormat:#"%02u:%02u:%02u", hours, mins, secs];
//call uptadeTime again after 1 second
[self performSelector:#selector(updateTime) withObject:self afterDelay:1];
}
Hope this will help. Thanks

Related

Get value from another method

I am trying to use data that I have placed on the same class but in a different method (I believe that is the terminology) but I cannot seem to access this data for some odd reason. I can do so when I place it all together (in the timer) but that would consume a TONNE of memory would it not since it would be setting this data over and over. Anyway, this is my code so far:
/////////////////////////////////SET TIME/DAYS///////////////////
currentTime = [NSDate date];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setTimeStyle:NSDateFormatterShortStyle];
self.timeNow.text = [timeFormatter stringFromDate:currentTime];
NSDate *lesson1Start = [timeFormatter dateFromString:#"8:40"];
NSDate *lesson2Start = [timeFormatter dateFromString:#"9:35"];
NSDate *recessStart = [timeFormatter dateFromString:#"10:30"];
NSDate *caregroupStart = [timeFormatter dateFromString:#"10:50"];
NSDate *lesson3Start = [timeFormatter dateFromString:#"11:00"];
NSDate *lesson4Start = [timeFormatter dateFromString:#"11:55"];
NSDate *lunchStart = [timeFormatter dateFromString:#"12:50"];
NSDate *lesson5Start = [timeFormatter dateFromString:#"1:30"];
NSDate *lesson6Start = [timeFormatter dateFromString:#"2:20"];
NSDate *endDay = [timeFormatter dateFromString:#"3:10"];
}
//////////////////////////END SET TIMES/////////////////////////
- (void)updateTime {
NSString *mondayDay = (#"Monday");
NSString *tuesdayDay = (#"Tuesday");
NSString *wednesdayDay = (#"Wednesday");
NSString *thursdayDay = (#"Thursday");
NSString *fridayDay = (#"Friday");
[updateTimer invalidate];
updateTimer = nil;
currentTime = [NSDate date];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setTimeStyle:NSDateFormatterShortStyle];
self.timeNow.text = [timeFormatter stringFromDate:currentTime];
updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:#selector(updateTime)
userInfo:Nil repeats:YES];
///////Check day/time & update lesson/////
if (self.dayNow.text == mondayDay && self.timeNow.text == lesson1Start) {
NSLog(#"");
}
As you can see, I cannot use "lesson1Start" since it is not in - (void)updateTime.
Would it be fine if I did bundle it all noting that it would be setting this data over and over since it is placed in the timer.
PS: I am trying to check if when the lesson starts and if the time is when the lesson starts then the lesson would appear. In this case I just have NSLog(#"").
You can do as...
Lets consider your code is in class ClassRoom;
#interface ClassRoom
{
NSArray *scheduleArray; //instance variable
}
you can create a NSArray *scheduleArray; for holding //you have to allocate and init it in implementation file
NSDate *lesson1Start = [timeFormatter dateFromString:#"8:40"];
NSDate *lesson2Start = [timeFormatter dateFromString:#"9:35"];
NSDate *recessStart = [timeFormatter dateFromString:#"10:30"];
NSDate *caregroupStart = [timeFormatter dateFromString:#"10:50"];
NSDate *lesson3Start = [timeFormatter dateFromString:#"11:00"];
NSDate *lesson4Start = [timeFormatter dateFromString:#"11:55"];
NSDate *lunchStart = [timeFormatter dateFromString:#"12:50"];
NSDate *lesson5Start = [timeFormatter dateFromString:#"1:30"];
NSDate *lesson6Start = [timeFormatter dateFromString:#"2:20"];
NSDate *endDay = [timeFormatter dateFromString:#"3:10"];
add all above dates in scheduleArray.(Hope you know how to add items in NSArray.)
Now you can write updateTime as
- (void)updateTime {
NSString *mondayDay = (#"Monday");
NSString *tuesdayDay = (#"Tuesday");
NSString *wednesdayDay = (#"Wednesday");
NSString *thursdayDay = (#"Thursday");
NSString *fridayDay = (#"Friday");
[updateTimer invalidate];
updateTimer = nil;
currentTime = [NSDate date];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setTimeStyle:NSDateFormatterShortStyle];
self.timeNow.text = [timeFormatter stringFromDate:currentTime];
updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:#selector(updateTime)
userInfo:Nil repeats:YES];
///////Check day/time & update lesson/////
for(NSDate * date in scheduleArray){
here you will get above saved dates use them to your need.
}
}
Hope it helps !

How to update UILabel frequently?

I want to update text for label frequently but it seems not working.
for (int i = 0; i <100; i++)
{
mylabel.text =[NSString stringWithFormat:#"%d", i];
}
Does anyone suggest for me an idea ? I thought. Maybe, we should update text label in multiple threads.
Watch is best example hope it will help you....
int second,minute; //set second = 0 and minute = 0
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
- (void)updateCounter:(NSTimer *)theTimer {
second++;
if(second < 60)
{
if (second < 10)
{
timerLbl.text = [NSString stringWithFormat:#"00:0%d", second];
}
else
{
timerLbl.text = [NSString stringWithFormat:#"00:%d",second];
}
}
else
{
minute = second / 60;
int sec = second % 60;
if (minute < 10 && sec < 10)
{
timerLbl.text = [NSString stringWithFormat:#"0%d:0%d", minute, sec];
}
if(minute < 10 && sec >= 10)
{
timerLbl.text = [NSString stringWithFormat:#"0%d:%d", minute, sec];
}
if (minute >= 10 && sec < 10)
{
timerLbl.text = [NSString stringWithFormat:#"%d:0%d", minute, sec];
}
if(minute >= 10 && sec >= 10)
{
timerLbl.text = [NSString stringWithFormat:#"%d:%d", minute, sec];
}
}
}
Add below code in viewDidLoad
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5f
target:self
selector:#selector(showTime)
userInfo:NULL
repeats:YES];
- (void)showTime
{
NSDate *now=[NSDate date];
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:#"HH:mm:ss"];
timeLabel.text=[dateFormatter stringFromDate:now];
}
Hope this answer will help you....
use NSTimer for the regular interval and call the method where the lable is printed let suppose
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(targetMethod:)
userInfo:nil
repeats:Yes];
in the target method print the label on text
-(void)targetMethod:(NSTimer *)timer{
NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#" HH:MM:SS"];
NSString* str = [formatter stringFromDate:date];
label.text = str;
}
try this it will work surely

Objective-c timer wont invalidate

Here is my situation: I am making a countdown app which works fine but does not appear to stop when I call [stopWatchTimer invalidate];, and I have no idea why. Here is my code:
- (IBAction)btnStartPressed:(id)sender {
//Start countdown with the time on the Date Picker.
timeLeft = [pkrTime countDownDuration];
[self currentCount];
lblTimer.text = time; //sets the label to the time set above
pkrTime.hidden = YES;
btnStart.hidden = YES;
btnStop.hidden = NO;
//Fire this timer every second.
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/1.0
target:self
selector:#selector(reduceTimeLeft:)
userInfo:nil
repeats:YES];
}
- (void)reduceTimeLeft:(NSTimer *)timer {
//Countown timeleft by a second each time this function is called
timeLeft--;
// Get the system calendar
NSCalendar *sysCalendar = [NSCalendar currentCalendar];
// Create the NSDates
NSDate *date1 = [[NSDate alloc] init];
NSDate *date2 = [[NSDate alloc] initWithTimeInterval:timeLeft sinceDate:date1];
// Get conversion to months, days, hours, minutes
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *conversionInfo = [sysCalendar components:unitFlags fromDate:date1 toDate:date2 options:0];
int sec = [conversionInfo second];
int min = [conversionInfo minute];
int hour = [conversionInfo hour];
NSString *seconds = [NSString stringWithFormat:#"%d",sec];
NSString *minutes = [NSString stringWithFormat:#"%d",min];
if (sec <= 9)
seconds = [NSString stringWithFormat:#"0%d", sec];
if (min <= 9)
minutes = [NSString stringWithFormat:#"0%d", min];
if ([conversionInfo hour] == 0)
time = [NSString stringWithFormat:#"%#:%#", minutes, seconds];
else
time = [NSString stringWithFormat:#"%d:%#:%#", hour, minutes, seconds];
lblTimer.text = time; //sets the label to the time set above
NSLog(#"%d", timeLeft);
if (timeLeft == 0) {
[self timerDone];
[stopWatchTimer invalidate];
stopWatchTimer = nil;
}
}
-(void)timerDone {
pkrTime.hidden = NO;
btnStart.hidden = NO;
btnStop.hidden = YES;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Timer Done" message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alert show];
[self playAlert];
}
Please let me know what the problem is... I cannot find a problem with my code anywhere!
In your btnStartPressed: method, you have nothing preventing a second NSTimer from being allocated and assigned to stopWatchTimer. If you press the button twice, you'll end up with two timers, but only one will ever be invalidated.
Add something like:
if (stopWatchTimer) return;
To the beginning of btnStartPressed:. If that doesn't fix the problem, then there isn't enough context to know for sure what is going on beyond conjecturing that timeLeft is zero?
What Nate said, but here is another explanation.
Imagine if you do this (where stopWatchTimer is a global or instance variable, doesn't matter):
stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:....];
Now, do this:
stopWatchTimer = nil;
[stopWatchTimer invalidate];
The timer won't invalidate, but it'll still fire. stopWatchTimer is a reference to the object. It isn't the object itself. Thus, when you assign a second timer to stopWatchTimer, you are overwriting the reference to the first timer, but that timer is still going to fire!

How to countdown from a NSDate and display it in hours and minutes

I'm trying to countdown from a NSDate and display it in hours and minutes. Like this: 1h:18min
At the moment my date is updating to a UILabel and counting down but displaying like this:
Here's the code I'm using. A startTimer method and a updateLabel method
- (void)startTimer {
// Set the date you want to count from
// convert date string to date then set to a label
NSDateFormatter *dateStringParser = [[NSDateFormatter alloc] init];
[dateStringParser setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.000Z"];
NSDate *date = [dateStringParser dateFromString:deadlineDate];
NSDateFormatter *labelFormatter = [[NSDateFormatter alloc] init];
[labelFormatter setDateFormat:#"HH-dd-MM-yyyy"];
NSDate *countdownDate = [[NSDate alloc] init];
countdownDate = date;
// Create a timer that fires every second repeatedly and save it in an ivar
NSTimer *timer = [[NSTimer alloc] init];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateLabel) userInfo:nil repeats:YES];
}
- (void)updateLabel {
// convert date string to date then set to a label
NSDateFormatter *dateStringParser = [[NSDateFormatter alloc] init];
[dateStringParser setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.000Z"];
NSDate *date = [dateStringParser dateFromString:deadlineDate];
NSDateFormatter *labelFormatter = [[NSDateFormatter alloc] init];
[labelFormatter setDateFormat:#"HH-dd-MM"];
NSTimeInterval timeInterval = [date timeIntervalSinceNow]; ///< Assuming this is in the future for now.
self.deadlineLbl.text = [NSString stringWithFormat:#"%f", timeInterval];
}
thanks for any help
- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval
{
NSInteger ti = (NSInteger)interval;
NSInteger seconds = ti % 60;
NSInteger minutes = (ti / 60) % 60;
NSInteger hours = (ti / 3600);
return [NSString stringWithFormat:#"%02i:%02i:%02i", hours, minutes, seconds];
}
Since you use NSTimeInterval ,you are getting the time interval ,ie the difference, in seconds, to display it in hours and minutes you need to apply mathematics logic and convert it!
You many need a few loops to do it.
try this
Regards

NSTimeinterval problem for date in iphone sdk

I am converting the date into NSTimeinterval like the code below:
NSDate *currentDate = [NSDate date];
NSTimeInterval currentyInterval = [appDelegate setTimeInterval:currentDate];
NSDate *expiryDate = [appDelegate setReverseDate:warrObj.expiredOn];
NSTimeInterval expiryInterval = [appDelegate setTimeInterval:expiryDate];
//Here I am getting the nil value and exception is generated.
//It happens only in 3.1
-(NSTimeInterval )setTimeInterval:(NSDate *)selectedDate
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init] ;
[dateFormatter setDateFormat:#"dd-MMM-yyyy 00:00:00"];
NSString *currStr = [dateFormatter stringFromDate:selectedDate];
NSDate *newCurrentDate = [dateFormatter dateFromString:currStr];
NSTimeInterval timeInterval = [newCurrentDate timeIntervalSinceReferenceDate];
[dateFormatter release];
return timeInterval;
}
Can anyone suggest me how to get rid of this.
Thanks to all,
Madan.
NSTimeInterval is just a typedef for double, it is not an object:
Getting a time interval:
NSTimerInterval timeInterval = [[NSDate date] timeIntervalSinceReferenceDate];
NSDate *expiryDate = [appDelegate setReverseDate:warrObj.expiredOn];
NSTimeInterval expiryInterval = [expiryDate timeIntervalSinceReferenceDate];
Creating a date from a time interval:
NSTimeInterval oneHour = 60*60;
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval - oneHour];