Reputation: 417
I have a money counter that increases over time which I want to animate, I'm using the below extension to run the animation but the issue is that it animates the entire label when I only want the digits that are changing to be animated.
I figured I'd split the digits up and animate each individual digit on its own, the problem is I can't figure how to break down the number and get specific digits.
is there a way I can go about breaking the number down and getting the individual digits or a better way of running the animation on individual numbers?
func pushTransition(duration:CFTimeInterval) {
let animation:CATransition = CATransition()
animation.timingFunction = CAMediaTimingFunction(name:
kCAMediaTimingFunctionEaseInEaseOut)
animation.type = kCATransitionPush
animation.subtype = kCATransitionFromTop
animation.duration = duration
self.layer.add(animation, forKey: kCATransitionPush)
}
if let aLabel = self.money{
aLabel.pushTransition(duration: 0.2)
aLabel.text = "$\(strRoundDollars)"
money.sizeToFit()
}
Upvotes: 3
Views: 84
Reputation: 22487
Firstly, you want to use NumberFormatter
rather than simple String interpolation, to make sure you always have the correct number of decimal places & currency sign, etc. for your locale/currency. Then all you need to do is map the .characters
property of the String back into an array of Strings:
let dollars = 123.4
let n = NumberFormatter()
n.numberStyle = .currency
n.locale = Locale.autoupdatingCurrent // or whatever locale you want
if let text = n.string(from: NSNumber(value: dollars)) {
text // "$123.40"
let charactersAsStrings = text.characters.map({String($0)})
charactersAsStrings // ["$", "1", "2", "3", ".", "4", "0"]
}
Many thanks to @Sulthan for pointing out that my first answer using String(format: "$%0.2f", dollars)
was shoddy :)
Upvotes: 2
Reputation: 207
That's actually a more tricky animation and I don't think it's possible to achieve that with just one label. My idea would be to replace your current label with a horizontal stack view. If your number is, let's say 100.00$, then add 7 labels to the stack, each just displaying one digit (including the "," and "$"). Now whenever your current value changes, all you have to do is find out which of the digits have changed. For that you can compare the characters before changing the value, with the characters after changing the value. The characters are a property of every string. Now that you know which values to change, you can iterate over all the subviews in your stack, animating each of the digits separately. I know, it's a much more complicated view hierarchy, but the results will be nice.
Upvotes: 0