Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
So, please don't take everything I typed and generalize it, because it's not for everyone.

I do understand where Dejo, Balamw and the others are coming from though. And frankly, they are probably better suited to help you than I am. I don't have a lot of experience with Objective-C and Cocoa, not like they do, having mostly come into it recently.

Back to the code, here is a photo of my connections (ignore canceBigtimer). What you say is true I don't know how NSTimer works entirely , just some parts, I realize that and it is one of the reason I postpone my timer for a future update (need to study it).

I have two timers, because, like I said.. I don't have full knowledge of timers. I know now that 1 timer is enough, even if I use two timers and start them at the same time, the log only shows 1 loop and the countdown in separate labels show e.g. 59 in one and 58 in another and so on.

Ok, how about we work on making 1 timer work then ? The code you posted is very complicated and I don't think it has to be this complicated. Going 1 timer would simplify this.

I see your Start Button is associated to 3 actions. Is this really what you want ? Let's simplify this. As an exercise, make 1 method, call it startTimer (like I did) and have only that action associated with your start button. From there, you can call the other methods yourself as needed.

Once you have modified the code in this way, post again what you have in full, what it is doing and what you think it should be doing. We'll go from there.

You mention my two global variables, It makes sense that the timer does not stop because the variables are outside the method that creates the timer. is that whats going on?

No, the variables are "fine" where they are. They would be better positionned in the @interface block and declared as instance variables, but implementation scope globals work too.

What you need to do however is reset those if you want your timer to start back at 0. Somewhere in your "stop/reset" code, there needs to be an initialization of those back to 0 :

Code:
seconds = 0;
minutes = 0;

If your Cancel button is what should reset it, then this should be right now in newActionTimer. But ideally, we'll get rid of that function when you simplify the code down to 1 timer.

Look at my NSLog outputs in my screenshot earlier. There's 3 methods there. updateLabel, cancelTimer, startTimer. This should have given you a big indication of how not complicated you should have made this.

If you want 3 buttons, start, reset, stop, you'd technically need 4 methods, as follows :

Code:
-(IBAction) startTimer: (id) sender;
-(IBAction) stopTimer: (id) sender;
-(IBAction) resetTimer: (id) sender;
-(void) updateLabel;

One to update the label as needed, one to start the timer, one to stop it and one to reset it.

Also, NSTimer is not your timer. The timer is what you are creating with ATimerViewController. You need to grasp this. NSTimer simply calls methods, in this case, it should be update label. That's about all it should be doing. Both the stop and reset methods should release the NSTimer object instance. startTimer should always create a new one. However, reset should be the one to set back seconds/minutes to 0.
 
That's a very good explanation Knight, I'm starting to understand some things better. Let me go do some stuff (eat, banks, etc) and I'll post an updated code with the startTimer method you mention and continue with that 1 timer. I'll be back soon.

Thank you once again
 
By the way, what's with 3rd person reference? the OP? you can call me Nekbeth or Chrystian, it's a lot more polite. Maybe you guys have a way to refer to someone , I don't know.

I appologize for that. I didn't recall your name. I was replying to KnightWRX, so I took a shorcut (original poster).

I won't do that any further.

I through together a simple program that I think does exactly as you want. It is a Mac version, but the different there is trival, and instead of a picker, it is a text field the user enters a time into for the timer duration. You will need to change the NSTextFields into UITextFields.

The bulk of the code is exactly what I posted before, but I modified the EchoIt method to work with an NSDate. I implemeted it in the appDelegate, and you are using your viewController. That doesn't change the code any, and your way is more correct.

I can email you the whole project as a zip if you want. It is about 2.5 meg. Just PM me your email address.

Code:
//
//  timertestAppDelegate.m
//  timertest
//
//  Created by Warren Holybee on 4/27/11.
//  Copyright 2011 Warren Holybee. All rights reserved.
//

#import "timertestAppDelegate.h"

@implementation timertestAppDelegate

@synthesize window, timeTextField, elapsedTimeTextField, timeLeftTextField;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
	// Insert code here to initialize your application 
}

-(IBAction)startButton:(id) sender {
	// myTimer is declared in header file ...
	
	if (myTimer!=nil) { // if the pointer already points to a timer, you don't want to 
		//create a second one without stoping and destroying the first
		
		[myTimer invalidate];
		[myTimer release];
		[startDate release];
	}
	
	// Now that we know myTimer doesn't point to a timer already..

	startDate = [[NSDate date] retain]; // remember what time this timer is created and started
										// so we can calculate elapsed time later

	
	NSTimeInterval myTimeInterval = 0.1; // How often the timer fires.
	myTimer = [NSTimer scheduledTimerWithTimeInterval:myTimeInterval target:self selector:@selector(echoIt) 
											 userInfo:nil repeats:YES];
	[myTimer retain];
}

-(IBAction)cancelIt:(id) sender {
	[myTimer invalidate];
	[myTimer release];  // This timer is now gone, and you won't reuse it.
	myTimer = nil;
}

-(void)echoIt {
	
	
	NSDate *now = [[NSDate date] retain];								// Get the current time
	NSTimeInterval elapsedTime = [now timeIntervalSinceDate:startDate]; // compare the current time to 
	[now release];																// our remembered time 
	
	NSLog(@"Elapsed Time = %.1f",elapsedTime);							// log it and display it in a textField
	[elapsedTimeTextField setStringValue:[NSString stringWithFormat:@"%.1f",elapsedTime]];
	 
	float timeValue = [timeTextField floatValue];						// timeValueTextField is where a user 
																		// enters the countdown length
																		
	float timeLeft = timeValue - elapsedTime;							// Calculate How much time is left.
	NSLog(@"Time Left = %.1f",timeLeft);									// log it and display it	
	[timeLeftTextField setStringValue:[NSString stringWithFormat:@"%.1f",timeLeft]];

	if (timeLeft < 0) {													// if the time is up, send "cancelIt:"
		[self cancelIt:self];											// message to ourself.
	}
	

}


	

@end

*edit:
If you like, later tonight I can show you how to do this as you first tried, by incrementing a seconds variable. Or wait for KnightWRX. My concern is accuracy of the timer. It might be off by several seconds after running an hour. That might not be an issue for your application, but you should be aware of it.
 
Last edited:
*edit:
If you like, later tonight I can show you how to do this as you first tried, by incrementing a seconds variable. Or wait for KnightWRX. My concern is accuracy of the timer. It might be off by several seconds after running an hour. That might not be an issue for your application, but you should be aware of it.

No, it very much is an issue, but I think this is an issue we should look into after the "timer" portion is working.

If we have a skeleton of a "timer" application working, with start/stop/resets going and a display that updates properly, then changing variables we increment based on the NSTimer firing to variables we increment based on the system clock is a trivial change.
 
No problem wlh99, it's alright. Guys, it turns out that today mmm... how do you say that in English ?? oh yeah, today I'm moving out of my house and I'll be busy most of the day but I hope I can work on that timer later in the afternoon (it's now 11 am here), I'll post it right away.

cheers,

wlh99, my e-mail is chryshiram@gmail.com

thanks
 
Ok fellows, thanks for the waiting, my new house is a mess but at least all my furniture is here now. I follow both of your examples ( wlh99's E-mail project and the great explanation that Knight showed here). I first started a new project in order to avoid confusion and made some changes, the result is what I think " a working timer " with start, stop and reset buttons. If I see the code now it seems a bit obvious why the timer never stopped before. I can tell you right now that I never reset the global variables inside any cancel or reset button thus the timer always continued. I think that the first variable (NSInteger seconds = 0 before the first method) gets called only once after that we reset it to 0 using the reset or cancel method (we can do it separately like knight said), in my case I assign reset to be the one to set that to 0 and cancel to invalid the timer.

Knight and wh99, if you like to see the project running and tell me your throughs, just give me your E-mail addresses (I have Warren's already) so I can share it with you. For obvious reasons I'm not posting it and if some of you wonder why, it's for same reasons nobody posted the complete working code despite being able to make a timer in less than 3 minutes. (yes, I know it's because you think it would not help me and I understand)

Special thanks to Knight and wh99 for their patience and instructions.

Thanks also to everyone who gave his opinion on this matter.

* Here is photo of the log and UI
 

Attachments

  • 1.jpg
    1.jpg
    119.1 KB · Views: 110
I first started a new project in order to avoid confusion and made some changes, the result is what I think " a working timer " with start, stop and reset buttons.

Maybe now you can go back and realize that you could have saved yourself and the rest of us a lot of time and effort by adhering to the recommendations from the links I posted. (Seriously, read them.)

Be specific. Be complete. Post complete, compilable code that demonstrates your problem. (If you need to, make a separate toy app, divide and conquer).

This is part of the "step back" that everyone was telling you to do early on, and is a basic skill for all kinds of troubleshooting. By breaking down the problem and explaining it to someone else you will often get an epiphany of your own. Like:
If I see the code now it seems a bit obvious why the timer never stopped before.
If the solution was handed to you it wouldn't (a) be that obvious [because you wouldn't understand it] and (b) wouldn't be exactly what you want.

For obvious reasons I'm not posting it and if some of you wonder why, it's for same reasons nobody posted the complete working code despite being able to make a timer in less than 3 minutes. (yes, I know it's because you think it would not help me and I understand)

I still don't think you understand the give and take of being a full participant in a forum like this.

It's your choice alone whether to add to the general knowledge pool or not. That's very different than responding to an ill-defined request for code.

For example, here's a thread I started earlier this month: https://forums.macrumors.com/threads/1133446/ I was playing with some code from various tutorials that was no longer functional, found a way to fix it and chose to give that solution back to the 'net and it was immediately useful for another user.

B
 
For example, here's a thread I started earlier this month: https://forums.macrumors.com/threads/1133446/ I was playing with some code from various tutorials that was no longer functional, found a way to fix it and chose to give that solution back to the 'net and it was immediately useful for another user.
B

That is good balamw, very good of your part to give back. But I decided to give back to only those who stayed with me to the End and showed true patience. Besides, this code is a piece of cake for all you.

*If your a beginner, just send me an E-mail and I will help you, PATIENTLY.
 
Ok fellows, thanks for the waiting, my new house is a mess but at least all my furniture is here now. I follow both of your examples ( wlh99's E-mail project and the great explanation that Knight showed here). I first started a new project in order to avoid confusion and made some changes, the result is what I think " a working timer " with start, stop and reset buttons. If I see the code now it seems a bit obvious why the timer never stopped before. I can tell you right now that I never reset the global variables inside any cancel or reset button thus the timer always continued. I think that the first variable (NSInteger seconds = 0 before the first method) gets called only once after that we reset it to 0 using the reset or cancel method (we can do it separately like knight said), in my case I assign reset to be the one to set that to 0 and cancel to invalid the timer.

Knight and wh99, if you like to see the project running and tell me your throughs, just give me your E-mail addresses (I have Warren's already) so I can share it with you. For obvious reasons I'm not posting it and if some of you wonder why, it's for same reasons nobody posted the complete working code despite being able to make a timer in less than 3 minutes. (yes, I know it's because you think it would not help me and I understand)

Special thanks to Knight and wh99 for their patience and instructions.

Thanks also to everyone who gave his opinion on this matter.

* Here is photo of the log and UI

Glad you got it working. Trust me when I say, it is not obvious, and that it now seems so to you is an accomplishment.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.