want to change my NSTimer code to to use applicationSignificantTimeChange
This is what I have right now.
Basically I want to change the timer, instead of changing every 5 seconds for example I want these textLabels to change at 12am every night anyone help me out?
//h file
NSTimer *timer;
IBOutlet UILabel *textLabel;
//m file
- (void)onTimer {
static int i = 0;
if ( i == 0 ) {
textLabel.text = #"iphone app";
}
else if ( i == 1 ) {
textLabel.text = #" Great App!";
}
else if ( i == 2 ) {
textLabel.text = #" WOW!";
}
else {
textLabel.text = #" great application again!!";
i = -1;
}
i++;
}
timer =[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
There are two things you can do to respond to a applicationSignificantTimeChange:
(1) Just implement applicationSignificantTimeChange: in your app delegate if you have a connection to the view controller that should be updated.
- (void)applicationSignificantTimeChange:(UIApplication *)application {
yourViewController.textLabel.text = #"random text";
}
(2) Subscribe to the UIApplicationSignificantTimeChangeNotification notification in the view controller that should get the update. You could perhaps put that code in viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(onSignificantTimeChange:)
name:UIApplicationSignificantTimeChangeNotification
object:nil];
}
- (void)onSignificantTimeChange:(NSNotification *)notification {
self.textLabel.text = #"random text";
}
You also need to call
[[NSNotificationCenter defaultCenter] removeObserver:self];
somewhere when your view controller is not longer needed.
the selector for the timer should be:
-(void) onTimer:(NSTimer *) timer
{
// yourcode
}
and called with:
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(onTimer:) userInfo:nil repeats:YES];
you need the "onTimer*:*"
[EDIT]
for calling a function that will go off at 12:am, for low-performance (i.e. not 12:00:00:0000) you could do the following for like an app that sits in the background:
NSTimeInterval minute = 60.0f
[NSTimer scheduledTimerWithTimeInterval:minute target:self selector:#selector(onTimer:) userInfo:nil repeats:YES]
-(void) onTimer:(NSTimer *) timer
{
NSDate *midnight = [NSDate dateWithNaturalLanguageString:#"today at 12:00 am"]; // unsure of this line
if ([midnight timeIntervalSinceDate:[NSDate date]] < 30.0f)
// set off alarm.
}
Seems pretty straightforward to me -- just create an NSDate for midnight, calculate the time interval of 24 hours in seconds, and create the NSTimer with
- (id)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
Related
I am developing one application,in that i have one requirement.onTyping method calls on textfield text change.when i enter first letter on textfield ontying method get called and timer starts &pause method called after 10 sec,pause method get called on continue on typing.But i want call pause method on last letter typing.how can i achieve this one
-(IBAction)onTyping:(id)sender
{
// [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:#selector(pause) userInfo:nil repeats:NO];
if(timer==nil)
{
timer=[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(pause) userInfo:nil repeats:NO];
}
[self fadeIn];
}
-(void)pause
{
[self fadeOut];
}
- (void)fadeIn
{
NSlog(#"fadeIn");
}
- (void)fadeOut
{
NSlog(#"fadeOut");
}
call that method textFieldShouldEndEditing: method of UITextFieldDelegate like bellow...
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[self pause];
return YES;
}
i am working in iPhone application, Using NSTimer to create time count to set in the screen like initially 100 then elapsed like 99,98,97 etc... if i have completed the game with available elapsed time, then i showed AlertView like successfully finished, the user press ok button navigate to previous screen, then again go to game screen, at the time ellapsed time start with previous elapsed time like 66,65,64 etc... i want, when the user go to game screen again the time count start with 100, how to fix this issue?, please help me
Thanks in Advance
I tried this:
- (void)viewDidLoad
{
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(elapsedTime) userInfo:nil repeats:YES];
}
-(void)elapsedTime
{
static int i = 100;
NSLog(#"i:%d",i);
lbl.text = [NSString stringWithFormat:#"%d",i];
i--;
if(i<0)
{
[timer invalidate];
timer = nil;
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[timer invalidate];
timer = nil;
[self.navigationController popViewControllerAnimated:YES];
}
Define int i as class variable in .h file
- (void)viewDidLoad
{
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(elapsedTime) userInfo:nil repeats:YES];
i = 100;
}
-(void)elapsedTime
{
i--;
if(i<0)
{
//show alertView here
[timer invalidate];
timer = nil;
}
}
Does any one want to teach me how to using loop process using NSTimer? I have 2 process timer to do, timer1 and timer2 repeated to n loop (timer1 -> timer2 -> timer1 -> timer2 and so on until n loop) that are triggered by a button. I am new to xcode. please teach me. both timer has input by user. please give me example if possible.
My code should be like this. Corret me if i'm wrong
- (void) timer2Elapsed:(NSTimer *) timer;
{
...
displayCountDown.text = [NSString stringWithFormat:#"%d : %d : %d", hour , minute, second];
}
- (void)timer1Elapsed: (NSTimer *) timer;
{
...
displayCountDown.text = [NSString stringWithFormat:#"%d : %d : %d", hour , minute, second];
}
My button who trigger the countdown:
- (IBAction)startBtn:(id)sender {
endSetTime = [NSDate timeIntervalSinceReferenceDate] + totalSecondTime;
endSetRest = [NSDate timeIntervalSinceReferenceDate] + totalSecondRest;
countdownTimer = [NSTimer scheduledTimerWithTimeInterval: 0.99 target: self selector: #selector(timer1Elapsed:) userInfo: nil repeats: YES];
}
someone here told me to using this code but i don't know what should i write inside and where to put it in? He said for looping? I don't know? And how to connect that code inside my button?
+ (void) startTimer:(id)timer
{
static int numberOfTimes = 0;
if(numberOfTimes >= 5)
{
numberOfTimes = 0;
return;
}
numberOfTimes ++;
[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(timer1Elapsed:) userInfo:nil repeats:NO];
}
Forget timers. Use performSelector:withObject:afterDelay: selector.
#interface CECountdown : NSObject {
NSDate *_startDate;
NSTimeInterval _countdownInterval;
}
#end
#implementation CECountdown
- (id)initWithCountdownInterval:(NSTimeInterval)interval {
self = [super init];
if(self) {
_countdownInterval = interval;
_startDate = [[NSDate date] retain];
}
return self;
}
- (void)dealloc {
[_startDate release];
[super dealloc];
}
- (void)method0 {
// Do something
[self performSelector:#selector(method1) withObject:nil afterDelay:0.3];
[self checkTimeout];
}
- (void)method1 {
// Do something
[self performSelector:#selector(method0) withObject:nil afterDelay:0.3];
[self checkTimeout];
}
- (void)invalidate {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(method1) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(method2) object:nil];
}
- (void)checkTimeout {
if([NSDate timeIntervalSinceReferenceDate] - [_startDate timeIntervalSinceReferenceDate] > _countdownInterval) {
[self invalidate];
}
}
- (void)didTapStartButton:(id)sender {
[self performSelector:#selector(method1) withObject:nil afterDelay:0.3];
}
#end
The following method causes a crash. The UI is like a button, which handles the start / stop functionality of the NSTimer. If the timer runs, a UILabel is updated. Using the viewDidLoad Method makes my timer work, stopping it works too, but starting it again crashes the app.
Removing the alloc in the viewDidLoad method and trying to use the start button causes a crash instantly. Even the NSLog(#"Start now");is not called.
Code:
- (void)tick {
NSLog(#"tick");
float value = [moneyLabel.text floatValue];
moneyLabel.text = [NSString stringWithFormat:#"%f", value + 1.0];
}
- (IBAction)startStopButtonClicked:(UIButton *)sender {
if ([sender.titleLabel.text isEqualToString:#"Start"]) {
NSLog(#"Start now");
if (timer) {
NSLog(#"Timer valid");
[timer fire];
} else {
NSLog(#"Timer is nil");
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(tick) userInfo:nil repeats:YES];
[timer fire];
}
NSLog(#"bla");
[sender setTitle:#"Stop" forState:UIControlStateNormal];
} else {
[timer invalidate];
timer = nil;
NSLog(#"Stopped.");
NSLog(#"Timer isValid: %#", timer);
[sender setTitle:#"Start" forState:UIControlStateNormal];
}
}
I don't see the need to call [NSTimer fire] at all; it should be enough to allow the timer to decide when to fire.
Firstly ensure that timer is nil (it should be if it's an instance variable of the object), although explicitly setting it to nil in - (id)init won't hurt.
Next I would use the state of the timer itself to determine whether start/stop has been pressed, not the text in the button:
- (IBAction)startStopButtonClicked:(UIButton *)sender
{
if (timer != nil)
{
NSLog(#"Stopping timer");
[timer invalidate];
timer = nil;
}
else
{
NSLog(#"Starting timer");
timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(tick)
userInfo:nil
repeats:YES];
}
[sender setTitle:(timer != nil ? #"Stop" : #"Start")
forState:UIControlStateNormal];
}
The code you have posted works as desired - just tested it in a new project, so the problem could be somewhere else. I tested it only by declaring the ivar NSTimer *timer; without any initialization in viewDidLoad: or the designated initializers...
I am using a sub class in my application, in which i am using nstimer to detect user idle/inactivity.
Here is a leak and it raised on every tap.
here is code of my class
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
isRootView=FALSE;
// Only want to reset the timer on a Began touch or an Ended touch, to reduce the number of timer resets.
NSSet *allTouches = [event allTouches];
if ([allTouches count] > 0) {
// allTouches count only ever seems to be 1, so anyObject works here.
UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
if (phase == UITouchPhaseBegan)
[self resetIdleTimer];
}
}
- (void)resetIdleTimer {
if (idleTimer)
{
if ([idleTimer isValid])
{
[idleTimer invalidate];
//[idleTimer release];
//idleTimer=nil;
}
}
maxIdleTime = 60;
if (!isRootView)
{
idleTimer = [NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:#selector(idleTimerExceeded) userInfo:nil repeats:NO];
[idleTimer retain];
}
else {
if ([idleTimer isValid])
{
[idleTimer invalidate];
//[idleTimer release];
//idleTimer = nil;
}
if ([resetTimer isValid]) {
[resetTimer invalidate];
resetTimer=nil;
}
}
}
- (void)idleTimerExceeded {
alert=[[UIAlertView alloc] initWithTitle:#"Confirmation!" message:#"Would you like to continue placing the order ?" delegate:self cancelButtonTitle:#"NO" otherButtonTitles:#"YES", nil];
alert.tag=100;
[alert show];
[alert release];
resetTimer=[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:#selector(resetApplication) userInfo:nil repeats:NO] ;
}
-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (alertView.tag==100 ) {
if (buttonIndex==1)
{
if ([resetTimer isValid]) {
[resetTimer invalidate];
resetTimer=nil;
}
}
else {
[self resetApplication];
}
}
}
-(void) resetApplication
{
isRootView=TRUE;
[alert dismissWithClickedButtonIndex:1 animated:YES];
if ([resetTimer isValid])
{
[resetTimer invalidate];
resetTimer=nil;
}
if (idleTimer)
{
[idleTimer invalidate];
[idleTimer release];
idleTimer = nil;
}
SushiTeriaAppDelegate *appDelegate=(SushiTeriaAppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate resetApp];
}
- (void)dealloc {
[super dealloc];
//[resetTimer release];
[alert release];
}
I have retain this timer. If dont retain then application get crashed.
Please guide me how to remove this leak
shivam
Use assigned property for timer variable.
ex.
NSTimer globalTimer;
#property (nonatomic, assigned) NSTimer globalTimer;
#synthesize globalTimer;
Now assign timer on this variable and use like self.globalTimer.
One thing is that always assign nil on variable after use. Do not release it another wise it will
crashed your application.
What is happening is, you are calling the resetIdleTimer method every time the user taps on the screen. This increases the retain count of the idleTimer every time because you have retained it. The reason your app crashes if you don't retain is because you get an autoreleased NSTimer object from NSTimer class method
idleTimer=[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:#selector(idleTimerExceeded) userInfo:nil repeats:NO];
This means that you cannot use this object outside that particular method as you do in your resetApplication method. Now you could check the retain count every time you retain it but that is a hassle. So what I suggest is you declare idleTimer as a retain property.
#property (retain) NSTimer *idleTimer;
and synthesize its setters and getters after implementation.
#synthesize idleTimer;
now use
self.idleTimer=[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:#selector(idleTimerExceeded) userInfo:nil repeats:NO];
and release idleTimer only in your dealloc.