AI and Software Development – Part 3.2

At this point in this experiment I’m feeling the dawn of that magical mental state we developers slip into – flow. The external world is now just a whispering distraction as my mind begins to focus itself on just the journey ahead. My sense of time simulataneousy expands and contracts as both the left and right hemispheres of my mind, the creative and the analytical, start listing to the same ambient soundscape playing on my headphones.

This feels different though. Now there is a second entity in this mindscape – an AI who speaks my language – SwiftUI.

The app is looking good but it’s not 95% perfect. Not yet “perfect enough” as we’d say at Boeing.

First, having the display of the time positioned right in the center of the view is rather distracting. It would make more sense to position this UX element below the three progress meters.

Me

Revise the code so that the Text that displays the time is below the nested circular progress views.

To display the current time below the nested circular progress views, you can modify the ZStack to be inside a VStack. Here’s the updated code:

… the code …

In this revised code, the Text view displaying the current time has been moved outside the ZStack and placed below it within the VStack. This will display the current time below the nested circular progress indicators.

Copy, paste, compile, run …

Perfect! Now onto polishing the progress meters.

They are functioning like I’d hoped for but my overarching vision for this app is Big~Bold~Beautiful! and while the three progress meters are rather beautiful they are a bit thin on being big and bold.

Plus, while I, as someone who has the code in front of them, understands that the red segment is for the seconds, the green is for the minutes and the blue is for the hours delivering the same information from more than one visual source, screen real-estate permitting of course, always delivers a better user experience.

Let’s push the envelope a bit and get ChatGPT 4 to fix two interface deficiencies at once.

Me

Revise the code so that the Text view used to display the time displays the seconds value in red, the minutes value in green and the hours value in blue. Set the width of the circular progress meters used to display the hours, minutes and seconds to 24.

To display the time with different colors for hours, minutes, and seconds, you can create separate Text views for each value and apply the desired colors. Additionally, you can set the lineWidth of the circular progress meters to 24. Here’s the updated code:

… the code …

In the updated code, separate Text views have been created for hours, minutes, and seconds, with their respective colors set using .foregroundColor(). The CircularProgressView struct now uses a lineWidth of 24 for the progress meters.

Copy, paste, compile, run …

Nice!

Big – check. Bold – check.

Beautiful – almost.

People love silky smooth animations. I love animations and I’m certain kittens love animations.

Time to see how far I can push this creative envelope of cooperation.

Me

Revise the code so that the circular progress meters include animations that rewind the value back to zero when they reach their maximum value.

To add animations for the circular progress meters when they reach their maximum values, you can use the .animation() modifier with a conditional check. Here’s the updated code:

… the code …

In the CircularProgressView struct, the .animation() modifier is added with a conditional check. If the progress value is 0, a linear animation with a duration of 0.2 seconds is applied, creating the rewind effect when the meter reaches its maximum value. Otherwise, the default animation is used.

Copy, paste, compile, run …

Beautiful – check!

Code complete. Thankyou ChatGPT 4!

At the end of this post is the final version of the app ready to be copied and pasted into your instance of Xcode. Something that was created entirely, with a bit of guidance from me, by ChatGPT 4.

But wait! There’s more!

At this point in this experiment I was so impressed that I decided to hire my first AI employee – ChatGPT 4 and its descendants. Obviously a press release from Forefront Systems Inc. is in order but I’ll save that for my next blog post.

import SwiftUI

struct ContentView: View {
    @State private var currentDate = Date()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        VStack {
            ZStack {
                CircularProgressView(progress: hoursProgress, color: .blue, size: 0.5)
                ZStack {
                    CircularProgressView(progress: minutesProgress, color: .green, size: 0.75)
                    CircularProgressView(progress: secondsProgress, color: .red, size: 1)
                }
            }
            HStack(spacing: 0) {
                Text("\(hoursString):")
                    .foregroundColor(.blue)
                Text("\(minutesString):")
                    .foregroundColor(.green)
                Text(secondsString)
                    .foregroundColor(.red)
            }
            .font(.system(size: 24))
            .fontWeight(.bold)
            .padding(.top)
        }
        .padding()
        .onReceive(timer) { _ in
            self.currentDate = Date()
        }
    }
    
    var hoursProgress: CGFloat {
        let components = Calendar.current.dateComponents([.hour], from: currentDate)
        let hours = CGFloat(components.hour ?? 0) / 12.0
        return hours
    }
    
    var minutesProgress: CGFloat {
        let components = Calendar.current.dateComponents([.minute], from: currentDate)
        let minutes = CGFloat(components.minute ?? 0) / 60.0
        return minutes
    }
    
    var secondsProgress: CGFloat {
        let components = Calendar.current.dateComponents([.second], from: currentDate)
        let seconds = CGFloat(components.second ?? 0) / 60.0
        return seconds
    }
    
    var hoursString: String {
        let components = Calendar.current.dateComponents([.hour], from: currentDate)
        return String(format: "%02d", components.hour ?? 0)
    }
    
    var minutesString: String {
        let components = Calendar.current.dateComponents([.minute], from: currentDate)
        return String(format: "%02d", components.minute ?? 0)
    }
    
    var secondsString: String {
        let components = Calendar.current.dateComponents([.second], from: currentDate)
        return String(format: "%02d", components.second ?? 0)
    }
}

struct CircularProgressView: View {
    var progress: CGFloat
    var color: Color
    var size: CGFloat
    
    var body: some View {
        Circle()
            .trim(from: 0, to: progress)
            .stroke(color, lineWidth: 24)
            .rotationEffect(.degrees(-90))
            .padding()
            .frame(width: 200 * size, height: 200 * size)
            .animation(progress == 0 ? .linear(duration: 0.2) : .default)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Published by Douglas J Farmer

I'm a freelance developer of Apple ecosystem apps including the iPhone, iPad and Mac.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: