How to animate incrementing number in UILabel
Solution 1
You could use a flag to see if it has to go up or down. Instead of a for loop, use a while loop. In this way, you are creating a loop that keeps going, so you have to find a way to stop it also, f.e. by a button press.
Solution 2
I actually made such a class just for this called UICountingLabel:
http://github.com/dataxpress/UICountingLabel
It allows you to specify whether you want the counting mode to be linear, ease in, ease out, or ease in/out. Ease in/out starts counting slowly, speeds up, and then finishes slowly - all in whatever amount of time you specify.
It doesn't currently support setting the actual font size of the label based on the current value, though I may add support for that if it's a feature that's in-demand. Most of the labels in my layouts don't have a lot of room to grow or shrink, so I'm not sure how you want to use it. However, it behaves totally like a normal label, so you can change the font size on your own as well.
Solution 3
You can use GCD to shift delays to background threads.
Here is the example of value animation (from 1 to 100 in 10 seconds)
float animationPeriod = 10;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
for (int i = 1; i < 101; i ++) {
usleep(animationPeriod/100 * 1000000); // sleep in microseconds
dispatch_async(dispatch_get_main_queue(), ^{
yourLabel.text = [NSString stringWithFormat:@"%d", i];
});
}
});
Solution 4
Here @malex's answer in swift 3.
func incrementLabel(to endValue: Int) {
let duration: Double = 2.0 //seconds
DispatchQueue.global().async {
for i in 0 ..< (endValue + 1) {
let sleepTime = UInt32(duration/Double(endValue) * 1000000.0)
usleep(sleepTime)
DispatchQueue.main.async {
self.myLabel.text = "\(i)"
}
}
}
}
However, I strongly recommend simply downloading this class from GitHub and dragging it into your project, I've resorted to using it because the timing in my code doesn't seem to adjust properly for lower/higher count numbers. This class works great and looks very good. See this medium article for reference.
Solution 5
There you have it without blocking sleeps! stick this to a UILabel and it counts up and down from the value currently displaying, cleaning non numbers first. Adjust from Double to Int or Float if needed.
yourlabel.countAnimation(upto: 100.0)
another simple alternative
extension UILabel {
func countAnimation(upto: Double) {
let from: Double = text?.replace(string: ",", replacement: ".").components(separatedBy: CharacterSet.init(charactersIn: "-0123456789.").inverted).first.flatMap { Double($0) } ?? 0.0
let steps: Int = 20
let duration = 0.350
let rate = duration / Double(steps)
let diff = upto - from
for i in 0...steps {
DispatchQueue.main.asyncAfter(deadline: .now() + rate * Double(i)) {
self.text = "\(from + diff * (Double(i) / Double(steps)))"
}
}
}
}
Related videos on Youtube
Darren
Updated on July 09, 2022Comments
-
Darren almost 2 years
I have a label showing a number and I want to change it to a higher number, however I'd like to add a bit of flare to it. I'd like to have the number increment up to the higher number with an ease inout curve so it speeds up then slows down. This answer shows how to make it increment (the 2nd answer, not the accepted answer) but I'd rather animate it so I could also make it increase in size slightly then shrink again as well as the ease inout curve. how to do a running score animation in iphone sdk
Any ideas how best to achieve this? Thanks
The start/end numbers will be user inputted and I want it to increment up the the end number in the same amount of time. So if I have start 10 end 100 or start 10 end 1000 I want it to count up to the end number in say 5 seconds.
-
Darren over 12 yearsMaybe I didn't explain myself enough. I have added more to my question. I can increment from 1 number to another using a for loop or a while loop. However I want it to count up by slowly speeding up then slowing down towards the end. And all to happen in a set amount of time.
-
Maarten Kesselaers over 12 yearsThen you can use 2 for-loops : - One to go up - And one to count down If you want to use a set amount of time, you'll have to use a timers, because otherwise, it happens as fast as the cpu can process it.
-
Darren over 12 yearsI don't need to count down. I can manage the loops, I just need to make the process happen in a certain amount of time. Can I put the count up loop in a timer to make the process happen in that amount of time, like with an animation? I thought timers would just tell it how often to happen.
-
Maarten Kesselaers over 12 yearsIf you see the first answer off the link you posted in your question, you can see that the timer will do the loop 15 times a second. You could use two loops with a different time. Another way is using the option
sleep(milliseconds)
in your loop. If you use a parameter for the wait time, you can decrease it via a custom algorithm. f.e. first time it runs 2000 ms, second time 2000ms - (i * 100ms), etc. -
Darren over 12 yearsThe problem with that is if I get a high number I have to count to. I wouldn't want to slow it down, i'd want to speed it up.
-
Maarten Kesselaers over 12 yearsThen you use the reverse off what I said : Take a start time of for example 1000ms 2nd time : 1000ms + i * 100 ms
-
Tim about 11 yearsGlad you like it :) If you have any feature requests feel free to post 'em on Github!
-
user3344977 over 9 yearsWhen I pasted this into Xcode, I got an error over "MAIN_QUEUE". I had to replace "MAIN_QUEUE" with "dispatch_get_main_queue()". Otherwise, this a great answer.
-
user3344977 over 9 yearsWell thank you for posting it. The heavily upvoted UICountingLabel answer above is not working correctly anymore so this was a nice alternative.
-
PaperThick about 9 yearsThis is a nice one but does anyone know how to get UICountingLabel to work with comma as a decimal point instead on period?
-
Simon almost 9 yearsI downloaded and tested a count from 0 to 30 in 3 seconds but did not work. The animation lasted closer to 4 seconds.
-
Reshad over 8 yearsthis gives me the value straight away.. without "animating" in swift 2.0 any idea why?
-
El Tomato over 7 yearsI don't think that's correct. I think sleepTime is misconfigured.
-
Travis M. over 7 yearsGreat catch. I corrected the answer to include the duration calculation, however, in my testing, the math is correct but there's a delay in the sleep/dispatch.main process so for the code above, it takes around 4 seconds to complete instead of 2 as entered.
-
Derek Saunders almost 5 yearsI implemented this into my own project, and it works perfectly.
-
Darren about 4 yearsThis question is 8 years old
-
Sergio about 4 yearsSimpler solution.
-
Lal Krishna almost 4 yearsThat gist code seems to be dead. Please update the answer. @TravisM.
-
Junaid over 2 yearsIs there a swift version of this?