UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Color variable isn't updating views on change

Forums > SwiftUI

Hey everyone, I have a color variable in my ViewModel that is marked with @Publisher, anytime the value changes it doesn't update the views.

Main View:

struct CreateHabit: View {
     @ObservedObject private var viewModel = ViewModel()

     Picker("Unit Picker", selection: $viewModel.unit) {
                            ForEach(Unit.allCases, id:\.self) { value in
                                Text("\(value.displayName)")
                            }
                        }
                        .tint(viewModel.selectedColor)
}

View Model:

extension CreateHabit {
     @MainActor class ViewModel: ObservableObject {
          @Published var selectedColor: Color

          init() {
               self.selectedColor = ConstantContainers().colorNames.randomElement()!
          }
     }
}

So on init, it sets the color randomly like I want it to. When selected color changes though, the tint of the picker stays what it was set to during init. Does anyone have any ideas?

I think it might have something to do how the tint modifier works. I have other views like the navbar buttons that both are updating correctly, yet they use foreground color. I'm going to continue to investigte this theory.

2      

I found a working solution, although it will be deprecated in future version of iOS.

Instead of tint, it works when using accentColor, like this:

Picker("Unit Picker", selection: $viewModel.unit) {
                            ForEach(Unit.allCases, id:\.self) { value in
                                Text("\(value.displayName)")
                            }
                        }
                        .accentColor(viewModel.selectedColor)

Does anyone know if there's a better solution given that it's going to be deprecated?

2      

Do you have a @StateObject somewhere for the published parameter, otherwise try changing this

@ObservedObject private var viewModel = ViewModel()

to

@StateObject private var viewModel = ViewModel()

The @StateObject creates the property wrapper for the observed object.

You can then use @ObservedObject in other views that needs to access the published objects.

The minimum declarations are @Published (in an observable object) and @StateObject to create the container and instantiate the object with an initial value.

Then add ObservedObject where needed, in other Views.

An alternative, depending on the app's use case, would be to create an @EnvironmnetObject, and pass and used it as an evnvironment parameter, as needed.

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.