GO FURTHER, FASTER: Try the Swift Career Accelerator today! >>

How to update clock seconds without rendering view every second?

Forums > SwiftUI

Hi, I'm trying to show the current time with seconds and use .numericText transition for the text the problem is when second change it render all of the view and the numericText make CPU high how can I fix it?

Thank you

import SwiftUI

struct InfoSwiftUIView: View {
    @State private var currentTime = Date()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        VStack {
            Spacer() // Push content downward slightly

            // Time with Numeric Transition
            if #available(macOS 13.0, *) {
                Text(timeString)
                    .font(.system(size: 28))
                    .scaleEffect(1.1)
                    .fontWeight(.bold)
                    .monospacedDigit()
                    .contentTransition(.numericText())
                    .animation(.default, value: timeString) // Add this line
                    .foregroundStyle(.white)
                    .padding()

                    .onReceive(timer) { input in
                        currentTime = input
                    }
                    .onTapGesture {
                        tempDelegate.openSplitViewControllerWindow()
                    }
            } else {
                Text(timeString)
                    .font(.largeTitle)
                    .fontWeight(.bold)
                    .monospacedDigit()
                    .foregroundStyle(Color(nsColor: .almostWhite))
                    .padding()
                    .onReceive(timer) { input in
                        currentTime = input
                    }
            }

            Spacer() // Add flexible space before the weather description
        }
        .frame(maxWidth: .infinity, maxHeight: switchernotchSize.height * 0.9, alignment: .top)
    }

    // Date String Formatter
    var dateString: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "EEEE, d MMM"
        return formatter.string(from: currentTime)
    }

    // Time String Fallback
    var timeString: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        return formatter.string(from: currentTime)
    }

   

Check out Natalia Panferova post called "Dynamic dates with monospaced digits in SwiftUI" if you on nilcoalescing . com, it might help.

   

@NigelGee I read it now it doesn't help me

   

@aviorrok claims:

the problem is when second change it render all of the view

I am not sure this is the case. @twoStraws has mentioned in several videos that SwiftUI is particularly clever at only changing the parts of the view that are directly affected by changing data. That is, SwiftUI won't redraw the entire screen on an iPad app, if the only thing that changed was the text in a text field.

What makes you think that "it renders all of the view..." each time a second changes?

Next, consider refactoring your code and moving the Text view to a separate SwiftUI file all together. Then add the component to your main view code. This way, you've moved the one-second update out of your larger parent view into an independent view all on its own.

Profiling with Instruments

Finally Xcode has a terrific set of tools called Instruments. Use this tool to allow Xcode to watch your code as it executes. You can measure how much memory is being used, how many cores. There's even an option to track SwiftUI itself and determine how many times the .body variable is called for each of your application's views. This may give you insight into what is getting redrawn when the second is updated in your text view.

Search the google for "Profiling Xcode Instruments Donny Wals" for a nice article from March 2023.

Keep Coding

Please return here and let us know how your solved your issue.....

   

@Obelix Hi, The high CPU is due .animtion that trigger the .contentTransition(.numericText()) and make high CPU don't know why it use high CPU

   

To update the clock seconds without rendering the entire view every second in SwiftUI, you can use a Timer to update only the seconds, rather than re-rendering the whole view. Here's an approach:

  1. Use a Timer to update the time: Create a timer that fires every second to update the current time. You can use the @State or @Published property wrappers to store the current time.

  2. Separate the seconds display: Instead of updating the whole view when the second changes, you can isolate the seconds display in its own view. This ensures that only the seconds value gets updated, without causing a full view refresh.

  3. Avoid unnecessary updates: You can optimize performance by only animating or updating the part of the view that displays the seconds. This can be done using conditional rendering or applying an animation only to the seconds text.

By using a Timer and updating only the necessary parts of the view (like the seconds), you can avoid high CPU usage and unnecessary rendering, ensuring smoother performance. Also, you can any time without any hastion about this kind of problime.

   

Hacking with Swift is sponsored by Alex.

SPONSORED Alex is the iOS & Mac developer’s ultimate AI assistant. It integrates with Xcode, offering a best-in-class Swift coding agent. Generate modern SwiftUI from images. Fast-apply suggestions from Claude 3.5 Sonnet, o3-mini, and DeepSeek R1. Autofix Swift 6 errors and warnings. And so much more. Start your 7-day free trial today!

Try for free!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.