NSTimer problem - iphone

I am using this code:
timer = [NSTimer scheduledTimerWithTimeInterval:2
target:self
selector:#selector(update)
userInfo:nil
repeats:YES];
...
-(void)update {
NSDate *date = [NSDate date];
NSString *Currentdate = [date descriptionWithCalendarFormat:#"%b %d, %Y %I:%M:%S %p"
timeZone:nil
locale:nil];
lbl.text = Currentdate;
}
It works fine but I want to change timer interval from 2 seconds to 1 second at run time. How can I do this?
Thanks in advance.

You can't change a timer interval after it's been created.
// You have to invalidate it...be careful,
// this releases it and will crash if done to an already invalidated timer
if (self.timer != nil) {
[self.timer invalidate];
self.timer = nil;
//... then declare a new one with the different interval.
timer = [NSTimer scheduledTimerWithTimeInterval:newInterval
target:self
selector:#selector(update)
userInfo:nil
repeats:YES];
}

Just invalidate the old timer and create new. I don’t think NSTimer supports changing the time interval, it would be an extra cruft both in the interface and the implementation.

Related

Adding pause functionality for NSTimer

First, here is some working code for a stopwatch in Xcode. I got two buttons, Startand Stop. Their titles change when the buttons are pressed. Now I want to add a pause functionality. I know that there are many threads about this, but (I don't know why) I was not able to get it working.
So what is the best approach to implement this function in my code?
I already tried to use a pause date and subtract it from my NSTimeIntervalbut got negative values ...
Thanks so far!
So I did this:
//use timer to update the ui only, store start date (NSDate) and time interval elapsed (NSTimeInterval)
//this is called when the timer is not running, nor paused - a sort of 'first run' function
-(void)onTimerStart
{
//zero the time elapsed
time_passed = 0;
//save the starting date
start_date = [NSDate date];
//start a timer that will update the ui in the onTimer function
timer = [NSTimer timerWithTimeInterval:1.0/10.0 target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
}
//called when the timer is running to pause it
-(void)onPause
{
//calculate the time that passed ( += not = )
time_passed += [[NSDate date] timeIntervalSinceDate: start_date];
//stop the timer
[timer invalidate];
//you can get rid of the start date now (using ARC ........)
}
//restarting the timer that was paused
-(void)onUnpause
{
//get new start date
start_date = [NSDate date];
//start the timer to update ui again
timer = [NSTimer timerWithTimeInterval:1.0/10.0 target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
}
//use this function if you are stopping - not pausing! - the timer.
-(void)onReset
{
//stop timer
[timer invalidate];
//calculate the final time that passed
//THE NEXT LINE IS PROBABLY WRONG AND HAS TO BE time_passed = 0; THEN IT WORKS
time_passed += [[NSDate date] timeIntervalSinceDate: start_date];
//get rid of the start date now
}
//use this function to update UI - this is what gets called by the timer
-(void)onTimer
{
//when timer ticks use ([[NSDate date] timeIntervalSinceDate: start_date] + time_passed)
//to get the amount of time passed for display
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self onTimerStart];
}
WORKING CODE:
#pragma mark - Timer
- (void)timer
{
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss.S"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
timerLabel.text = timeString;
}
#pragma mark - Stopwatch
- (IBAction)onStartPressed:(UIButton *)sender
{
if ([sender.titleLabel.text isEqualToString:#"Start"] && (![timer isValid]) && ([timerLabel.text isEqualToString:#"00:00.0"]))
{
startDate = [NSDate date];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:#selector(timer)
userInfo:nil
repeats:YES];
}
}
- (IBAction)onStopPressed:(UIButton *)sender
{
if ((![timer isValid]) && ([sender.titleLabel.text isEqualToString:#"Reset"]))
{
[timer invalidate];
timer = nil;
timerLabel.text = #"00:00.0";
[sender setTitle:#"Stop" forState:UIControlStateNormal];
}
if (([timer isValid]) && ([sender.titleLabel.text isEqualToString:#"Stop"]))
{
[timer invalidate];
timer = nil;
[sender setTitle:#"Reset" forState:UIControlStateNormal];
}
}
There is no pause/resume functionality built into NSTimer, so you have to implement something along the lines of:
//THIS IS PSEUDOCODE
//use timer to update the ui only, store start date (NSDate) and time interval elapsed (NSTimeInterval)
//this is called when the timer is not running, nor paused - a sort of 'first run' function
- onTimerStart:
{
//zero the time elapsed
time_passed = 0;
//save the starting date
start_date = [NSDate date];
//start a timer that will update the ui in the onTimer function
[timer start]
}
//called when the timer is running to pause it
- onPause
{
//calculate the time that passed ( += not = )
time_passed += [[NSDate date] timeIntervalSinceDate: start_date];
//stop the timer
[timer invalidate];
//you can get rid of the start date now
}
//restarting the timer that was paused
- onUnpause
{
//get new start date
start_date = [NSDate];
//start the timer to update ui again
[timer start];
}
//use this function if you are stopping - not pausing! - the timer.
- onReset
{
//stop timer
[timer invalidate];
//calculate the final time that passed
time_passed += [[NSDate date] timeIntervalSinceDate: start_date];
//get rid of the start date now
}
//use this function to update UI - this is what gets called by the timer
- onTimer
{
//when timer ticks use ([[NSDate date] timeIntervalSinceDate: start_date] + time_passed)
//to get the amount of time passed for display
}

NSTimer not running

I've got a program in which I want to code a timer which checks wether the user is idle or not. For that I wrote following code:
if (!idleTimer) {
NSLog(#"make");
idleTimer=[[NSTimer alloc]initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:10.0]interval:10 target:self selector:#selector(idleTimerExceeded) userInfo:nil repeats:NO];
NSLog(#"madetimer with: %f, %#", idleTimer.timeInterval, idleTimer.fireDate);
}else {
NSLog(#"no reset timer: %f", idleTimer.timeInterval);
if (fabs([idleTimer.fireDate timeIntervalSinceNow]) < 9) {
NSLog(#"reset");
[idleTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:10]];
}
}
But somehow my logs show that the interval is always 0.0000 . Which means that something is wrong here. Can anybody help me?
ive never seen a timer look so complicated. try this:
write a method that checks if the user is idle (lets say idleChecker)
then make the timer repeatable and calls that method idleChecker
[NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:#selector(idleChecker) userInfo:nil repeats:YES];
remember to declare the idleChecker method in the .h file
take note if u want to stop the timer event then you need to maintain a reference to it
NSTimer aTimer = [NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:#selector(idleChecker) userInfo:nil repeats:YES];
then to stop it
[aTimer invalidate];
as for checking if its running i would just stick a nslog message in there stating something like "check for idle user"

iOS Camera Countdown Timer

I'm looking for the cleanest way to have a countdown timer fire when a user hits the 'take picture' button. Is there any easy way to do this?
One solution I'm thinking of is to just have a label that updates every second, but is there a way to get it working like Photobooth?
Also, at the last second before the photo is about to be taken I'd like for an image to be displayed briefly while the image is being taken. How can I go about this?
Any help would be great, thanks!
- (IBAction)takePicture:(id)sender {
theTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(updateLabel:) userInfo:nil repeats:NO];
}
- (void)updateLabel:(NSTimer *)timer {
_timeLabel.text = [NSString stringWithFormat:#"%d", time];
time = time - 1;
if (time == 0) {
[theTimer invalidate];
[_timeLabel performSelector:#selector(setText:) withObject:#"Photo taken!" afterDelay:1.0];
//Code for image shown at last second
} else {
theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateLabel:) userInfo:nil repeats:NO];
}
}
Hope this helps ;)

running a time interval computation in the background

I have a NSTimeInterval which is basically
NSTimeInterval interval = [date1 timeIntervalSinceDate: [NSDate date]];
I want this computation to be always running in the background when I am in a view X, so I can display a timer counting down in a UILabel.. how do I do this? It's like in the groupon iphone app, but it doesn't show it in details of seconds
You could use an NSTimer to get a method called at a set time interval (however this is all performed on the main thread, not on a background thread):
- (void)setupTimer {
//Start a timer to call update updateInterval: every 1 second
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(updateInterval:)
userInfo:nil
repeats:YES];
}
- (void)updateInterval:(NSTimer *)timer {
NSTimeInterval interval = [date1 timeIntervaleSinceDate:[NSDate date]];
//Do other things like updating the label
}

How do I link the iphones time to change a UILabel

I want to link the time on the iphone such as midnight to change the text of a UILabel to something else anyone help out?
Ive looked through the NSTimer and found nothing that works any help?
Try this:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(update:) userInfo:nil repeats:YES];
And...
- (void) update:(NSTimer *) timer {
myLabel.text = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle: NSDateFormatterLongStyle timeStyle: NSDateFormatterLongStyle];
}
There are two other ways: use -[performSelector:withObject:aterDelay:] (and NSObject has a class method to cancel such, or better,
your appDelegate can implement:
-(void)applicationSignificantTimeChange:(UIApplication *)app;
which will get called at midnight, carrier time update, and daylight savings time change