I have a UILabel with a value of 0, and an int with a value of 300. How do I use NSTimer to have the UILabel go from 0 to 300 in 2 seconds? I want it to look like it's being added up incrementally.
Thanks in advance!
Actually NSTimer precision is about 50-100 milliseconds so it can't be so smooth as you want. But you can schedule timer for 0.05 and measure how much time had really passed from the beginning. After use
value = timePassedInSeconds*300/2;
NSString* label = [NSString stringWithFormat:#"%d", value];
if this won't be smooth enough try to use display link instead of NSTimer.
What are you trying to do? Are you trying to show some sort of point/score animation? You can do what you want if you do the math and fire off the timer at the interval you want, but I doubt you'll get what you want. You might want to look at UIImageView and feed it an array of images to animate or do the animations yourself with by painting.
I figured out a different solution:
I knew I wanted the "count up" to last 3 seconds... which is 60*0.05... basically the timer is hitting the method 60 times to get to the total amount.
addUpAb = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(addUpTimer) userInfo:nil repeats:YES];
-(void)addUpTimer {
int addNo = abTOT / 60;
abInt += addNo;
abductionCount.text = [NSString stringWithFormat:#"%d", abInt];
if(abInt >= abTOT) {
[addUpAb invalidate];
abCount.text = [NSString stringWithFormat:#"%d", abTOT];
}
}
Related
I'm trying to implement a button that starts a timer after a random period of time (between 0-10s). While the timer is running it should update a label every 0.005s to show how much time has elapsed. The problem i'm having is 2-fold:
I'm not sure how to get the label to update with the elapsed time every 0.005s.
I'm having trouble getting the app to wait the random amount of time before starting timer. At present I'm using sleep(x) however it seems to cause the app to ignore all the other code in the if statement and causes the button image to freeze up (i.e. it looks like its still clicked).
Here is the code I have so far...
- (IBAction)buttonPressed:(id)sender
{
if ([buttonLabel.text isEqualToString:#"START"])
{
buttonLabel.text = #" "; // Clear the label
int startTime = arc4random() % 10; // Find the random period of time to wait
sleep(startTime); // Wait that period of time
startTime = CACurrentMediaTime(); // Set the start time
buttonLabel.text = #"STOP"; // Update the label
}
else
{
buttonLabel.text = #" ";
double stopTime = CACurrentMediaTime(); // Get the stop time
double timeTaken = stopTime - startTime; // Work out the period of time elapsed
}
}
If anyone has any suggestions on..
A) How to get the label to update with the elapsed time.
or
B) How to fix the 'delay' period from freezing up the app
... it would be really helpful as I'm pretty much stumped at this point. Thanks in advance.
You should use an NSTimer to do this. Try the code:
- (void)text1; {
buttonLabel.text = #" ";
}
- (void)text2; {
buttonLabel.text = #"STOP";
}
- (IBAction)buttonPressed:(id)sender; {
if ([buttonLabel.text isEqualToString:#"START"]) {
int startTime = arc4random() % 10; // Find the random period of time to wait
[NSTimer scheduledTimerWithTimeInterval:(float)startTime target:self selector:#selector(text2:) userInfo:nil repeats:NO];
}
else{
// I put 1.0f by default, but you could use something more complicated if you want.
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(text1:) userInfo:nil repeats:NO];
}
}
I'm not exactly sure how you want to update label based on the time, but if you post more code, or give an example, I'll post the code on how to do that, but it would just be using an NSTimer as well. Hope that Helps!
The answer to A could be:
Once the random amount of time has passed, (#MSgambel has a good suggestion), then execute:
timer = [NSTimer scheduledTimerWithTimeInterval:kGranularity target:self selector:#selector(periodicallyUpdateLabel) userInfo:nil repeats:YES];
(The above line could go into #MSgambel's -text2 method.)
That will call the -periodicallyUpdateLabel method once every kGranularity seconds, repeatedly. In that method, you could do things like update your label, check for user actions, or end the game if the time is up or some other condition has been met.
And here is the -periodicallyUpdateLabel method:
- (void)periodicallyUpdateView {
counter++;
timeValueLabel.text = [NSString stringWithFormat:#"%02d", counter];
}
You'll have to format the text differently to get what you want. Also, translate from the counter value to time using kGranularity. However, and this is what I found, there is only so many cpu cycles in iOS devices. Trying to go down to microsecond level made the interface sluggish and the time displayed started to drift from the actual time. In other words, you may have to limit your updates of the label to once every one hundredth of a second or tenths. Experiment.
I'm looking to make a UILabel display the current progress of a timer. Right now to get the current time left I call [timer1 timeLeft]; which returns an int. In this way I can update the label ONCE, at one instant. In what way can I update the label (mainLabel) constantly so that it is always displaying the current timer progress while being somewhat resource efficient?
Thanks for all your help!
Use following code for Countdown timer.
dblElapsedSeconds=0.0; //Declare this in header
tmrElapsedTime = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateElapsedTime) userInfo:nil repeats:YES]; //Declare timer variable in header
-(void)updateElapsedTime
{
dblElapsedSeconds += 1;
//double seconds = [[NSDate date] timeIntervalSinceDate:self.startTime];
int hours,minutes, lseconds;
hours = dblElapsedSeconds / 3600;
minutes = (dblElapsedSeconds - (hours*3600)) / 60;
lseconds = fmod(dblElapsedSeconds, 60);
[lblTimeElapsed setText:[NSString stringWithFormat:#"%02d:%02d",minutes, lseconds]];
}
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];
}
HI , i have made simple application with 5 view controllers with some functionality .. what i want to do now is add a time at the main screen . and it should b running till i quit from application .. i will move to other view controllers also but that timer would b running .. how i will have this functionality ??
Check out the "Timers" section here: http://www.iphoneexamples.com/
Also, refer to Apple's NSTimer Documentation
The most practical way to do this is to fake it - that is, just store the start timestamp, and don't bother to continuously maintain any kind of timePassed variable. This is both easier to code, and actually more reliable since it's stable.
Store an NSDate for the instant the timer was started, and whenever you want to display or update the timer, use NSDate's timeIntervalSinceNow method, which returns the number of seconds passed as an NSTimeInterval, which is basically a typedef for a double. Note: this function returns a negative number when called on a timestamp in the past, which will be the case here.
If part of your display is showing this time, you can update it every second (or even more often) with an NSTimer object that periodically called one of your methods which updates the display.
Sample code:
// In the initialization code:
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self
selector:#selector(secondPassed:) userInfo:nil repeats:YES];
// Later:
// (This code assumes #minutes < 60.)
- (void) secondPassed: (NSTimer:) timer {
NSTimeInterval secondsPassed = -1 * [self.timerStart timeIntervalSinceNow];
int minutes = (int)(secondsPassed / 60);
int seconds = (int)(seconds - minutes * 60);
NSString* timerString = [NSString stringWithFormat:#"%02d:%02d",
minutes, seconds];
[self updateTimerDisplay:timerString];
}
I have an int which defines the objectAtIndex, which gives it to the string, which then displays it in the UILabel, HOWEVER, when I modify the array (add a word to it in this case) when I have the UILabel go through the array it only displays the odd ones. I have done an NSLog and found out that it DOES PASS EVERY SINGLE THING to the string, but the Label isn't displaying every single one, it only does it the first time, then I modify the array, and it only does odd
edit: the code:
- (void) stuff {
NSArray *indivwords = [sentence componentsSeparatedByString:#" "];
count = [indivwords count]; //count=int
if (i < count) {
NSString *chunk = [indivwords objectAtIndex:i];
[word setText:chunk];
NSLog(chunk);
i++;
} else {
word.textColor = [UIColor greenColor];
[word setText:#"DONE"];
}
}
All of this is being controlled by an NSTimer, which sets it off based on a slider value. Also i is set to 0 in the IBAction
The IBAction code:
word.textColor = [UIColor whiteColor];
[timer invalidate];
i = 0;
speedd = (1/speed.value)*60;
timer = [NSTimer scheduledTimerWithTimeInterval:(speedd) target:self selector:#selector(stuff) userInfo:nil repeats:YES];
EDIT:
I fixed it! What I did was call this after i reached the count
-(void)stoptimer
{
[timer invalidate];
timer = [NSTimer scheduledTimerWithTimeInterval:(.01) target:self selector:#selector(empty) userInfo:nil repeats:YES];
}
empty is just a void with nothing in it, well, all I did was add a comment,
//don't look over here, nothing to see here, oh look at that
Somebody can close this if they want
You said the time interval of your NSTimer is controlled by a slider. Perhaps you are starting a new timer instance every time you change the slider value, so after a change you would have two timers running. The first one updates the label and increments i. The second one comes right after the first and finds i's value incremented, so it displays the next chunk instead of the current one.
Count the instances of your timer - NSLog the timer in the timer callback and compare the results - it may be that you're firing more than one.
My guess is that you have two different actions calling this method, when you think there should be one. I'd put a break point in there, and see if it stops where you think it should.