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      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

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.