Digits move sideways

I’m new to SwiftUI programming and am following a tutorial on how to make a digital clock. My problem is that the digits move slightly side ways as they update. I found someone suggesting using a invisible dummy text to control it but it’s not working for me. I don’t want to use a mono spaced text. Any suggestions?


struct ContentView: View {
    @State var date = Date()
    var body: some View {
        ZStack {
            //Background color
            Color.black
                .edgesIgnoringSafeArea(.all)
                //Dummy text set to be slightly visible for reference
            Text("00:00:00").opacity(0.3)
            .foregroundColor(.accentColor)
            .font(.system(size: 50, weight: .ultraLight, design: .default))    
        }
    }
    var timeFormat: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        return formatter
    }
    func timeString(date: Date) -> String {
        let time = timeFormat.string(from: date)
        return time
    } 
    var updateTimer: Timer {
        Timer.scheduledTimer(withTimeInterval: 1, repeats: true,
                             block: {_ in 
            self.date = Date()
        })
    }
    
}

Answered by Claude31 in 700886022

Could you post more complete code. Where do you use updateTimer ? With this, it does nothing except display 00:00:00

Accepted Answer

Could you post more complete code. Where do you use updateTimer ? With this, it does nothing except display 00:00:00

Oops I seem to have deleted more than my commented text in the first post. This would be the complete code.


struct ContentView: View {
    @State var date = Date()
    var body: some View {
        ZStack {
            Color.black
                .edgesIgnoringSafeArea(.all)
            Text("00:00:00").opacity(0.3)
            .foregroundColor(.accentColor)
            .font(.system(size: 50, weight: .ultraLight, design: .default))
            Text("\(timeString(date: date))")
                .foregroundColor(.white)
                .onAppear(perform: {let _ = self.updateTimer})
                .font(.system(size: 45, weight: .ultraLight, design: .default))
        }
    }
    var timeFormat: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        return formatter
    }
    func timeString(date: Date) -> String {
        let time = timeFormat.string(from: date)
        return time
    } 
    var updateTimer: Timer {
        Timer.scheduledTimer(withTimeInterval: 1, repeats: true,
                             block: {_ in 
            self.date = Date()
        })
    }
    
}

Monospaced is your best option. This makes a monospaced version of the current font

struct ClockView: View {
    @State private var date: String = "00:00:00"

        var body: some View {
            ZStack {
                Color.black
                    .edgesIgnoringSafeArea(.all)
                Text(date)
                    .foregroundColor(.white)
                    .font(.system(size: 45, weight: .ultraLight, design: .default).monospaced())
                    .foregroundColor(.secondary)
                    .onReceive(ClockView.timer) { _ in
                        self.date = ClockView.timeFormat.string(from: Date())
                    }
            }
     }

    static let timer = Timer.publish(every: 0.2, on: .main, in: .common).autoconnect()

    static var timeFormat: DateFormatter {
         let formatter = DateFormatter()
         formatter.dateFormat = "HH:mm:ss"
         return formatter
    }
}

You have somehow contradictory requirements : not a mono space font (I mean fixed width) but text keeping the exact same alignment…

What you could try is to display separately hours, min, sec in 3 Text and set the position of each.

You could try if

.font(.system(size: 50, weight: .ultraLight, design: .default)).monospacedDigit()    

gives the intended result.

Yes, that worked exactly as I wanted. Thanks!

Digits move sideways
 
 
Q