Search code examples
swifttimerswiftuidouble

How to prevent Text from shaking when value changes and format double value both sides of the decimal point?


I've a countdown timer. When the numbers keep changing, the text moves horizontally and it feels like it is shaking too much, because I'm updating the timer every 0.1 seconds.

How to prevent the text from shaking? Here's full code:

struct CountDownTimerView: View {
    
    @ObservedObject var timer = CountdownTimer(seconds: 15)
    
    var body: some View {
        Text(String(format: "%.1f", timer.time))
            .font(Font.system(size: 144).weight(.light))
    }
}

class CountdownTimer: ObservableObject {
    @Published var time: Double
    
    /// time interval in seconds
    let interval = 0.1
    
    lazy var timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { _ in
        self.update()
    }
    
    init(seconds: Double) {
        time = seconds
        timer.fire()
    }
    
    func update() {
        if self.time-interval <= 0 {
            self.time = 0
            timer.invalidate()
        } else {
            self.time -= interval
        }
    }
}

I want to display the time for the double value 7.329523 and as 07.3. I'm able to achieve either formatting before the decimal point like "07" using String(format: "%02d", Int(timer.time)) or after the decimal point like "7.3" using (String(format: "%.1f", timer.time). How to format both sides of the decimal point?


Solution

  • Here is it (you have to give full width of output prepending 0, so [0 7 . 3] is four chars, thus:

    let value: CGFloat = 7.329523
    Text(String(format: "%04.1f", value))
    

    output

    demo

    Tested with Xcode 12