SemC
August 7, 2024, 10:10am
1
Hi all,
I’m trying to recreate a progress bar for an onboarding process. I’m using BarProgressStyle with a customization feature but I can’t figure out to show it as I want and make it do what I want.
In the attachment, there is a screen showing the progress bar that I’m trying to recreate. This progress bar shows the progress when you go forward to the next screen but you can also go backwards by tapping on the rounded rectangles that are part of the progress bar.
Is there someone who can give some best practices or insights on how to do this?
Best,
Sem
Hi Sem,
I’m up for these kinds of challenges.
This is what I have come up with as a test project and these are the Views, Model and App components. Hope you can make sense of it.
App:
import SwiftUI
@main
struct OnBoardProgressApp: App {
@State var progressManager = ProgressModel()
var body: some Scene {
WindowGroup {
ContentView()
.environment(progressManager)
}
}
}
ContentView:
import SwiftUI
struct ContentView: View {
@Environment(ProgressModel.self) var progressModel
var body: some View {
VStack {
ProgressBar()
Spacer()
HStack {
Button(action: {
if progressModel.progressAmount > 1 {
progressModel.progressAmount -= 1
}
}, label: {
Text("Previous")
})
Button(action: {
if progressModel.progressAmount < 6 {
progressModel.progressAmount += 1
}
}, label: {
Text("Next")
})
}
}
.padding()
}
}
#Preview {
ContentView()
.environment(ProgressModel())
.preferredColorScheme(.dark)
}
ProgressBar:
import SwiftUI
struct ProgressBar: View {
@Environment(ProgressModel.self) var progressModel
var body: some View {
HStack {
ForEach(1...6, id: \.self) { index in
if index <= progressModel.progressAmount {
Button(action: {
progressModel.progressAmount = index
}, label: {
ProgressSegment(color: .white)
})
.buttonStyle(.plain)
} else {
Button(action: {
progressModel.progressAmount = index
}, label: {
ProgressSegment(color: .gray)
})
.buttonStyle(.plain)
}
}
}
}
}
#Preview {
ProgressBar()
.preferredColorScheme(.dark)
.environment(ProgressModel())
}
ProgressSegment:
import SwiftUI
struct ProgressSegment: View {
let color: Color
var body: some View {
Rectangle()
.fill(color)
.frame(height: 4)
.cornerRadius(2)
}
}
#Preview {
ProgressSegment(color: .white)
.preferredColorScheme(.dark)
}
ProgressModel:
import Foundation
import Observation
@Observable class ProgressModel {
var progressAmount = 1
}
2 Likes
SemC
August 13, 2024, 6:36am
3
Perfect solution. Thanks a lot!
That’s great. Glad to be of assistance.