Fuego DeBassi
Fuego DeBassi

Reputation: 3017

Passing a ColorPicker selection to a different view in SwiftUI

I think I'm close but also missing something fundamental here with SwiftUI and passing data.

  1. I have a top-level Color var called "masterColor" which I house in my "DataModel" struct.
  2. Then in my view "NightLight", I have a system "ColorPicker", where I use a local var "localColor" to reflects whatever value the ColorPicker has.
  3. Finally I have a "BackgroundControllerView", which sets a background color (which I would like to read the dataModel.masterColor)

What I'm trying to do set the dataModel.masterColor (which my whole app can see) equal to my localColor, which only NightLight can see. I've simplified the structure here a bit but the thrust of the question is about how to take local data and set something global equal to it for the rest of the app to see.

struct DataModel {
    @State var masterColor = Color.red
}

struct NightLight: View {
    @Binding var dataModel: DataModel
    @State var localColor = Color.blue
    
    var body: some View {
        ColorPicker("Pick Color", selection: $localColor)
        // Question: somehow set dataModel.masterColor = localColor ??
    }

}

struct BackgroundControllerView: View {
    @Binding var dataModel: DataModel
    
    var body: some View {
        Rectangle()
            .fill(dataModel.masterColor)
    }
}

Very much appreciate any help!

Upvotes: 2

Views: 473

Answers (1)

aheze
aheze

Reputation: 30336

There's no need to have a separate localColor. You can directly pass in $dataModel.masterColor to the picker.

struct NightLight: View {
    @Binding var dataModel: DataModel /// no need for extra `localColor`
    
    var body: some View {
        ColorPicker("Pick Color", selection: $dataModel.masterColor)
    }
}

Also, remove the @State from masterColor -- you want the @State to be applied to DataModel, not the properties inside.

struct DataModel {
    var masterColor = Color.red /// no @State here
}

struct NightLight: View {
    @Binding var dataModel: DataModel
    
    var body: some View {
        ColorPicker("Pick Color", selection: $dataModel.masterColor)
    }
}

struct BackgroundControllerView: View {
    @Binding var dataModel: DataModel
    
    var body: some View {
        Rectangle()
            .fill(dataModel.masterColor)
    }
}

struct ContentView: View {
    @State var dataModel = DataModel() /// use `@State` here instead
    
    var body: some View {
        VStack {
            NightLight(dataModel: $dataModel)
            BackgroundControllerView(dataModel: $dataModel)
        }
    }
}

Result:

Changing color picker color changes the background color

Upvotes: 1

Related Questions