TimeInterval function setting with UIPicker - iphone

I have following part of code. It is executing when user will select any time interval from UIpicker.
if([[arrayNo objectAtIndex:row] isEqualToString:#"1 minutes"])
time=60;
if([[arrayNo objectAtIndex:row] isEqualToString:#"5 minutes"])
time=300;
[NSTimer scheduledTimerWithTimeInterval:60 target:self selector:#selector(updateMethod) userInfo:nil repeats:YES];
I am defining two time in UIPicker "1 minutes" and "5 minutes". Suppose once user will select "1 minutes" then function "updateMethod" will be call after 1 minutes of time period. But let suppose user again change his time to "5 mnutes" from UIPicker. Then what will happen? Is timer will be set to "5 minutes" OR it will be set to "1 minutes" and "5 minutes" both?
How will I design code to set function calling for one time only?
Help me in it concept?

Every time this is called, you will schedule a new timer, so in your example, you will get both.
I generally discourage scheduledTimerWithTimeInterval:... for basically this reason. You now have no way to cancel your timer. You should create an NSTimer* ivar like this:
#interface ... { }
#property (nonatomic, readwrite, retain) NSTimer *updateTimer;
#end
#implementation ...
#synthesize updateTimer=updateTimer_;
- (void)setUpdateTimer:(NSTimer *)aTimer {
if (aTimer != updateTimer_) {
[aTimer retain];
[updateTimer_ invalidate];
[updateTimer_ release];
updateTimer_ = aTimer;
}
}
...
self.timer = [NSTimer timerWithTimenterval:60 target:self selector:#selector(updateMethod) userInfo:nil repeats:YES];
This will automatically clear the old timer whenever you set the new timer.
Do note that basing logic on UI strings (#"1 minutes") will break localization if you ever want this to be translated into other languages. Instead, you would normally either just use row to decide the value, or you would add small dictionaries or objects to arrayNo that would hold the label and the value.

Related

Scroll UISlider Automatically

So currently I have a UISlider in a UIViewcontroller that is meant to start animations within subviews when the user slides.. Basically when the user slides I have this battery with a filling in it that fills the empty battery image with a bar to indicate power within a cell, and the user can slide to see the energy the battery has at certain times of the day.
At the moment, when the View loads I would like the UISlider to AUTOMATICALLY start sliding from the beginning of the slider and scroll to the end within, lets say 5 seconds.
I implemented a loop that cycles through all the values of the uislider using this loop
for (int i = 0; i < [anObject count] - 2; i++)
{
sleep(.25);
NSUInteger index = (NSUInteger)(slider.value + 0.5); // Round the number.
[slider setValue:index animated:YES];
}
[anObject count] - 2 is equal to 62 at this time of day but will change and increment every 15 seconds because I'm fetching data from a server.
But that aside, why doesn't this work? The loop?
EDIT:
So heres what I did with NSTIMER
[NSTimer timerWithTimeInterval:0.25 target:self selector:#selector(animateSlider) userInfo:nil repeats:NO];
and animateSlider looks like this:
- (void)animateSlider:(NSTimer *)timer
{
NSLog(#"Animating");
NSUInteger index = (NSUInteger)(slider.value + 0.5); // Round the number.
[slider setValue:index animated:YES];
}
But no luck... Why isn't NSTimer "firing"..... I remmeber vaguely there was a method that FIRES an nstimer method but not sure if that's needed...
EDIT:
Ahh it does need "Fire"....
NSTimer *timer = [NSTimer timerWithTimeInterval:0.25 target:self selector:#selector(animateSlider) userInfo:nil repeats:NO];
[timer fire];
But for some reason it only fires once.... Any ideas ?
"for some reason it only fires once..."
If you changed the NSTimer set up to this:
NSTimer *timer =
[NSTimer scheduledTimerWithTimeInterval:0.25
target:self
selector:#selector(animateSlider:)
userInfo:nil
repeats:YES];
This would schedule the timer on the current run loop immediately.
And since the "repeats" parameter is "YES", you'd then repeat the timer every quarter second, until you invalidate the timer (which you should do when the ending condition is reached, like when the slider reaches its destination).
P.S. You'd need to change the selector method declaration of your timer's target slightly. According to Apple's documentation, "The selector must correspond to a method that returns void and takes a single argument. The timer passes itself as the argument to this method."
So declare "animateSlider" like this instead:
- (void)animateSlider: (NSTimer *) theTimer;

objective-c: Animate button before timer ends

I'm working on a very simple iPhone game that involves choosing the right colored button as many times in a row based on a randomized voice prompt. I have it set up so that if the button is one color and gets clicked, it always goes to a hard-coded color every time (e.g. if you click red, it always turns blue). The color change method is set up in an IBOutlet. I have a timer set up in a while loop, and when the timer ends it checks if the player made the right selection. The problem is that the button color change does not occur until after the timer runs out, and this causes a problem with the method used to check the correct answer. Is there a way to make this color change happen instantly? From what I've searched I know it has something to do with storyboard actions not occurring until after code executes, but I haven't found anything with using a timer. Here is a section of the method that calls the timer if the answer is correct:
BOOL rightChoice = true;
int colorNum;
NSDate *startTime;
NSTimeInterval elapsed;
colorNum = [self randomizeNum:middle];
[self setTextLabel:colorNum];
while (rightChoice){
elapsed = 0.0;
startTime = [NSDate date];
while (elapsed < 2.0){
elapsed = [startTime timeIntervalSinceNow] * -1.0;
NSLog(#"elapsed time%f", elapsed);
}
rightChoice = [self correctChoice:middleStatus :colorNum];
colorNum = [self randomizeNum:middle];
}
One of two things stood out
You're using a while loop as a timer, don't do this - the operation is synchronous.
If this is run on the main thread, and you code doesn't return, your UI will update. The mantra goes: 'when you're not returning you're blocking.'
Cocoa has NSTimer which runs asynchronously - it is ideal here.
So let's get to grips with NSTimer (alternatively you can use GCD and save a queue to an ivar, but NSTimer seems the right way to go).
Make an ivar called timer_:
// Top of the .m file or in the .h
#interface ViewController () {
NSTimer *timer_;
}
#end
Make some start and stop functions. How you call these is up to you.
- (void)startTimer {
// If there's an existing timer, let's cancel it
if (timer_)
[timer_ invalidate];
// Start the timer
timer_ = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:#selector(onTimerFinish:)
userInfo:nil
repeats:NO];
}
- (void)onTimerFinish:(id)sender {
NSLog(#"Timer finished!");
// Clean up the timer
[timer_ invalidate];
timer_ = nil;
}
- (void)stopTimer {
if (!timer_)
return;
// Clean up the timer
[timer_ invalidate];
timer_ = nil;
}
And now
Put your timer test code in the onTimerFinish function.
Make an ivar that stores the current choice. Update this ivar when a choice is made and make the relevant changes to the UI. Call stopTimer if the stop condition is met.
In the onTimerFinished you can conditionally call and startTimer again if you desire.
Hope this helps!

creating a timer for a level in iphone game

Im trying to add a timer to my game so that the user knows how long they have spent playing a level. Ive figured out that I can initialize a timer the following way:
bool showTimer = YES;
NSDate startDate;
UILabel timerLabel; // initialized in viewDidLoad
-(void) showElapsedTime: (NSTimer *) timer {
if (showTimer) {
NSTimeInterval timeSinceStart;
if(!startDate) {
startDate = [NSDate date];
}
timeSinceStart = [[NSDate date] timeIntervalSinceDate:startDate];
NSString *intervalString = [NSString stringWithFormat:#"%.0f",timeSinceStart];
timerLabel.text = intervalString;
if(stopTimer) {//base case
[timer invalidate];
}
}
}
- (void) startPolling {
[NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:#selector(showElapsedTime:) userInfo:nil repeats:YES];
}
I start the startPolling method in the viewDidLoad. When I run the app, I do see the timer and it tracks the time but when I exit the app and re-enter it, the timer doesnt pause. I'm also not sure how to handle going to another view (like the options menu) and then coming back to this view. I understand NSDefaults and NSCoding and I see how I could save the current value on the timer as a Coding object, keeping a seperate key-value pair in a plist for every level but this seems cumbersome.
Is there a better way to keep track of how long the user spends in a level?
Instead of doing the calculation (subtracting the start time from the current time) every time, since all you care about is an elapsed time, just have a variable like NSTimeInterval elapsedTime that you start at 0 and add time to every time that the timer fires. (If you want to track it to 0.1 seconds like in your example, just divide by 10 before displaying it.) This way, you can pause it whenever you want and it will just continue on from where it was before when it starts up again.

Ios UILabel update performance

in my application i have an UILabel showing a time updated every second.
I have also draggable objects in the screen.
When I hide the label or i stop the timer everything is perfect but when i start the timer the animation performance of dragging objects go down.
I put the UILabel updating in a separate thread but no luck.
I need help friends :)
This is my code:
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(onTimer:) userInfo:nil repeats:YES];
-(void) onTimer:(NSTimer *)timer;
{
timeInterval ++;
int hours = (int)timeInterval / 3600;
int minutes = (timeInterval %3600)/ 60;
int seconds = ((timeInterval%3600)%60);
NSString *timeDiff = [NSString stringWithFormat:#"%d:%02d:%02d", hours,minutes,seconds];
[NSThread detachNewThreadSelector:#selector(setText:) toTarget:self.time withObject:timeDiff];
}

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