I am using a class to store an array of colors and persist the index of that array corresponding to a user selected color in UserDefaults.
class AccentColorManager: ObservableObject {
let colors: [Color] = [.orange, .yellow, .green, .blue, .purple, .brown, .cyan, .indigo, .mint, .teal]
@Published var accentColor: Color = .orange // on initial launch orange is default color
@Published var accentColorIndex: Int = 0 {
didSet {
accentColor = colors[accentColorIndex]
saveAccentColorIndex()
objectWillChange.send()
}
}
init() {
loadAccentColorIndex()
}
private let accentColorIndexKey = "AccentColorIndex"
private func saveAccentColorIndex() {
UserDefaults.standard.set(accentColorIndex, forKey: accentColorIndexKey)
}
private func loadAccentColorIndex() {
if let storedIndex = UserDefaults.standard.value(forKey: accentColorIndexKey) as? Int {
accentColorIndex = storedIndex
}
}
}
The view below presents the user with a list of colors. Regardless of what color the user selects, the very last list item is always selected, and subsequent selections have no effect.
struct ActiveColorSectionView: View {
@EnvironmentObject var accentColorManager: AccentColorManager
var body: some View {
Section(header: Text("Active Color")) {
VStack(alignment: .leading) {
ForEach(accentColorManager.colors.indices, id: \.self) { index in
Button(action: {
accentColorManager.accentColorIndex = index
}) {
HStack {
Text(accentColorManager.colors[index].description)
Spacer()
Circle()
.frame(width: 20, height: 20)
.foregroundColor(accentColorManager.accentColorIndex == index ? accentColorManager.colors[index] : .clear)
.overlay(
Circle()
.stroke(Color.primary, lineWidth: 2)
)
}
}
.foregroundColor(accentColorManager.colors[index])
.padding(.vertical, 5)
}
}
}
.listRowBackground(Color(UIColor.systemBackground))
}
}
I suspect that my use of using an index array may be problematic here, but I cannot see the specific problem and this seems more appropriate than saving a Color type to UserDefaults.
Additionally, I am using the AccentColorManager class as an environment variable:
@main
struct my_app: App {
@StateObject private var accentColorManager = AccentColorManager()
var body: some Scene {
WindowGroup {
WelcomeView()
.environmentObject(accentColorManager)
}
}
}




