Mick
Mick

Reputation: 417

Getting a specific decimal place

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

Answers (2)

Grimxn
Grimxn

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

Florensvb
Florensvb

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

Related Questions