Cocoa Touch - Timers - cocoa-touch

How can I make a timer that counts down from 3 and then runs a method? How would I do that?

Is that different from a timer counting from 0 to 3? It will still wait three seconds, either way.
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:#selector(myMethod:) userInfo:nil repeats:NO];

Better way might be to use performSelector:withObject:afterDelay: method:
[self performSelector:#selector(myMethod) withObject:nil afterDelay:3.0f];
Or in case method takes 1 parameter:
[self performSelector:#selector(myMethod:) withObject:parameter afterDelay:3.0f];
If method takes multiple parameters you'll need to use NSInvocation class

- (void) handleTimer: (NSTimer *) timer
{
do some work here...
} // handleTimer
// at some point in your controller
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 3.0
target: self
selector: #selector(handleTimer:)
userInfo: nil
repeats: NO];

Related

Fire IBAction automatically

I have a button and want to fire it automatically by itself without touch.
Is it possible?
-(IBAction)xxx:(id)sender
My answer assumes you have the method:
- (IBAction)someAction:(UIButton *)sender {
}
and that you have a reference to the button in an instance variable named someButton.
If you just need to "fire it" now, simply call it:
[self someAction:someButton];
If you need to "fire it" once, but later, you can do:
// call it 5 seconds from now
[self performSelector:#selector(someAction:) withObject:someButton afterDelay:5.0];
If you want to fire it repeatedly, use a timer:
myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(buttonTimerFired) userInfo:nil repeats:YES];
- (void)buttonTimerFired {
[self someAction:someButton];
}
Action can be called like every regular function - you can do it by running a timer on something else.
You should use NSTimer for doing your work.
[NSTimer scheduledTimerWithTimeInterval: 0.01f target: self selector: #selector(BtoonMethod) userInfo: nil repeats: NO];
-(void)BtoonMethod
{
// write code for call yor button method
}

How to stop NSTimer started on button click in this timer callback method

I am having problems with stoping NSTimer started on button click. [timer invalidate] and timer = nil; just do nothing neither when I am trying to stop it viewWillDisappear nor in method invoked by method which is being invoked by this timer. However when I start my timer in viewWillAppear and invalidate it in viewWillDisappear everything is fine.
I suppose there might be an issue in thread I am starting the timer from. Can you help with that?
I looked through all answers here regarding NSTimer not stopping, but they didn't help to solve the problem.
The way I initialize my timer:
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(oneSecondPassedSinceRoundStarted) userInfo:nil repeats:YES];
The ways I tried to stop it:
[self.timer invalidate];
[timer invalidate];
It's funny how quick you can answer your own question after you asked for a help. No matter how long you have been struggling to find the answer before by yourself:
[self performSelectorOnMainThread:#selector(stopTimer) withObject:nil waitUntilDone:YES];
And the selector:
- (void) stopTimer
{
[timer invalidate];
timer = nil;
}
I have created and tested this:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(oneSecondPassedSinceRoundStarted:) userInfo:nil repeats:YES];
}
-(void)oneSecondPassedSinceRoundStarted:(NSTimer *)time {
// Do what You want
NSLog(#"CALLING!");
}
-(IBAction)buttonAction:(id)sender {
NSLog(#"Stop timer!");
[myTimer invalidate];
myTimer = nil;
}
And it is working nice.
Note: You forget to add colon after oneSecondPassedSinceRoundStarted.

NSTimer doesn't call method

I'm really frustrated now, googled the whole internet, stumbled through SO and still didn't find a solution.
I'm trying to implement an NSTimer, but the method which I defined doesn't get called. (seconds are set correctly, checked it with breakpoints). Here is the code:
- (void) setTimerForAlarm:(Alarm *)alarm {
NSTimeInterval seconds = [[alarm alarmDate] timeIntervalSinceNow];
theTimer = [NSTimer timerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
}
- (void) showAlarm:(Alarm *)alarm {
NSLog(#"Alarm: %#", [alarm alarmText]);
}
The object "theTimer" is deined with #property:
#interface FooAppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> {
#private
NSTimer *theTimer;
}
#property (nonatomic, retain) NSTimer *theTimer;
- (void) setTimerForAlarm:(Alarm *)alarm;
- (void) showAlarm:(Alarm *)alarm;
What am I doing wrong?
timerWithTimeInterval simply creates a timer, but doesn't add it to any run loops for execution. Try
self.theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
instead.
Also don't forget to check if
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds
target:(id)target
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats
is called in the main thread.
You've created an NSTimer object but you haven't scheduled it to be run. timerWithTimeInterval:target:selector:userInfo:repeats: creates a timer that you can schedule to run later, for example, to create a timer at application launch and have it start counting when the user presses a button. Either call
[[NSRunLoop currentRunLoop] addTimer:theTimer forMode:NSDefaultRunLoopMode]
at the end of setTimerForAlarm or replace
theTimer = [NSTimer timerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
with
theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
which creates a timer and immediately schedules it.
Well you may want to actually schedule your NSTimer on the run loop :) instead of timerWithTimeInterval use scheduledTimerWithTimeInterval.
theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds
target:self
selector:#selector(showAlarm:)
userInfo:alarm repeats:NO];
While all of the answers are right, there is an even simpler solution that doesn't involve a NSTimer at all. Your setTimerForAlarm: implementation can be reduced to one simple line:
[self performSelector:#selector(showAlarm:) withObject:alarm afterDelay:[[alarm alarmDate] timeIntervalSinceNow]]

Calling a method after a delay?

How can I call a method after a short delay? (For example, after resignFirstResponder is called.)
u can call method after delay using perform select: like
[self performSelector:#selector(keyboardShow) withObject:nil afterDelay:0.5];
You can use either timer like this
timer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:#selector(taskOnTimer) userInfo:nil repeats:NO];
OR use this
[self performSelector:#selector(playPages) withObject:nil afterDelay:10];

Delayed call, with possibility of cancelation?

How do I trigger a delay, let's say I want to call a method (once) in 3 seconds from now, and how do I cancel that call if I need to?
You can also use -[NSObject performSelector:awithObject:afterDelay:], and +[NSObject cancelPreviousPerformRequestsWithTarget:selector:object].
Use NSTimer. Use this to set up a call to method in three seconds time. It will only be called once:
[NSTimer scheduledTimerWithTimeInterval: 3
target: self
selector: #selector(method:)
userInfo: nil
repeats: NO];
method needs to look like this:
- (void) method: (NSTimer*) theTimer;
You can pass parameters into the method using userInfo (set to nil in the above example). It can be accessed in the method as [theTimer userInfo].
Use the invalidate method on NSTimer to cancel it.
in your header..
NSTimer *timer;
when you want to setup..
timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:#selector(yourMethod:) userInfo:nil repeats:NO];
when you want to cancel..
[timer invalidate];