How do I change another View's background color as same as ColorSettingView?

import SwiftUI

struct ColorSettingView: View {

    

    @Environment(.presentationMode) var presentation

    let brPlayer = SoundPlayer()

    @State private var bgColor = Color.white

    

    var body: some View {

                    

        ZStack{

            bgColor

                              .ignoresSafeArea()

                          VStack {

                              ColorPicker("Background Color", selection: $bgColor)

        

                Button (action: {brPlayer.brPlay()

                    self.presentation

                        .wrappedValue.dismiss()

                }, label: {

                    Image("Quit")

                        .resizable()

                        .aspectRatio(contentMode: .fit)

                        .padding(/@START_MENU_TOKEN@/[.leading, .bottom, .trailing]/@END_MENU_TOKEN@/)

                        .frame(width: 100.0, height: 100.0)

                    

                })

                          }

          

        }

        }

}

                            

            

struct ColorSettingView_Previews: PreviewProvider {

    static var previews: some View {

        ColorSettingView()

    }

}

//Another View like ContenViewX

struct ContentViewX: View {

 

    let kiPlayer = SoundPlayer()

    @State private var bgColor = Color.white

    @State var ColorSettingView = false

 

    

 var body: some View {

 

ZStack {

  

//    I also want to change this view as same as ColorSettingView

  bgColor

        .ignoresSafeArea()

  VStack {

     

      Button (action: {kiPlayer.kiPlay()

       

       self.ColorSettingView = true},  label: {Image("Setting")

         .resizable()

         .aspectRatio(contentMode: .fit)

         

       }

      )

    

    .sheet(isPresented: $ColorSettingView, content: {

        Game.ColorSettingView()}

    )

   

  }

}

 }

}

struct ContentViewX_Previews: PreviewProvider {

 static var previews: some View {

  ContentViewX()

 }

}

Answered by Claude31 in 712654022

There is a simpler way to do it, just with Sate and Binding

struct ColorSettingView: View {
    
    @Environment(\.presentationMode) var presentation
    @Binding var bgColor : Color

    var body: some View {
        
        ZStack{
            bgColor
                .ignoresSafeArea()
            VStack {
                ColorPicker("Background Color", selection: $bgColor)
                
                Button (action: {
                    self.presentation
                        .wrappedValue.dismiss()
                }) {
                    Text("Quit\n\(bgColor.description)")
                        .padding()
                    
                }
            }
            
        }
    }
}
                            
struct ContentView: View {
    
    @State var bg : Color = .white
    @State var colorSetting = false

    var body: some View {
        
        ZStack {
            //    I also want to change this view as same as ColorSettingView
            bg
                .ignoresSafeArea()
            VStack {
                
                Button("Show\n\(bg.description)") {
                    colorSetting = true
                }
                .sheet(isPresented: $colorSetting, content: {
                    ColorSettingView(bgColor: $bg)}
                )
                
            }
        }
    }
}

When you paste code, please use Paste And Match Style to avoid all extra blank lines. And use code formatter.

There seems to be an error in Environment var declaration.

But I could not test (some struct definitions are missing. Where is Game defined ?

struct ColorSettingView: View {
    
    @Environment(\.presentationMode) var presentation // <<-- Error here: needs \.
    @State private var bgColor = Color.white

    let brPlayer = SoundPlayer()
    
    var body: some View {
        
        ZStack{
            bgColor
                .ignoresSafeArea()
            VStack {
                ColorPicker("Background Color", selection: $bgColor)
                
                Button (action: {brPlayer.brPlay()
                    self.presentation
                        .wrappedValue.dismiss()
                }, label: {
                    Image("Quit")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .padding(/@START_MENU_TOKEN@/[.leading, .bottom, .trailing]/@END_MENU_TOKEN@/)
                        .frame(width: 100.0, height: 100.0)
                    
                })
            }
            
        }
    }
}
                            
            
struct ColorSettingView_Previews: PreviewProvider {
    static var previews: some View {
        ColorSettingView()
    }
}

struct ContentViewX: View {
    
    let kiPlayer = SoundPlayer()
    @State private var bgColor = Color.white
    @State var ColorSettingView = false  // <<-- Not very good idea to name as the struct. Change to colorSetting
    
    var body: some View {
        
        ZStack {
            //    I also want to change this view as same as ColorSettingView
            bgColor
                .ignoresSafeArea()
            VStack {
                
                Button (action: {kiPlayer.kiPlay()
                    
                    self.ColorSettingView = true},  label: {Image("Setting")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                    }
                )
                
                .sheet(isPresented: $ColorSettingView, content: {
                    Game.ColorSettingView()}
                )
                
            }
        }
    }
}

You should declare an @ObservedObject in ContentView for the color (note that to make it observable, you may have to embed as published in an observable struct)

@ObservedObject var setting: ColorSetting()

and declare an @EnvironmentObject in ColorSettingView

    @EnvironmentObject var setting: ColorSetting

Then when you present sheet:

        .sheet(isPresented: $colorSetting) { // Changed the name
            ColorSettingView().environmentObject(setting)  // THIS IS IMPORTANT
        }

Hope that works as I could not test.

This should work. I have simplified your code, but it should be easy to reintroduce missing parts.

The point was to create an ObservableObject class and use ObservedObject and Binding

class ColorSetting : ObservableObject {
    @Published var color: Color = .white
}

struct ColorSettingView: View {
    
    @Environment(\.presentationMode) var presentation
    @Binding var bgColor : Color     // bgColor is changed here but owned by another View

    var body: some View {
        ZStack{
            bgColor
                .ignoresSafeArea()
            VStack {
                ColorPicker("Background Color", selection: $bgColor)  // We change the color, and publish the change
                
                Button (action: {
                    self.presentation
                        .wrappedValue.dismiss()
                }) {
                    Text("Quit\n\(bgColor.description)")
                        .padding()
                    
                }
            }
            
        }
    }
}
                            
struct ContentView: View {
    
    @ObservedObject var bg = ColorSetting()      // We observe it
    @State var colorSetting = false

    var body: some View {
        
        ZStack {
            //    I also want to change this view as same as ColorSettingView
            bg.color
                .ignoresSafeArea()
            VStack {
                
                Button("Show\n\(bg.color.description)") {
                    colorSetting = true
                }
                .sheet(isPresented: $colorSetting, content: {
                    ColorSettingView(bgColor: $bg.color)  // we'll get color from ColorSettingView, by Binding
                     }
                )
                
            }
        }
    }
}
Accepted Answer

There is a simpler way to do it, just with Sate and Binding

struct ColorSettingView: View {
    
    @Environment(\.presentationMode) var presentation
    @Binding var bgColor : Color

    var body: some View {
        
        ZStack{
            bgColor
                .ignoresSafeArea()
            VStack {
                ColorPicker("Background Color", selection: $bgColor)
                
                Button (action: {
                    self.presentation
                        .wrappedValue.dismiss()
                }) {
                    Text("Quit\n\(bgColor.description)")
                        .padding()
                    
                }
            }
            
        }
    }
}
                            
struct ContentView: View {
    
    @State var bg : Color = .white
    @State var colorSetting = false

    var body: some View {
        
        ZStack {
            //    I also want to change this view as same as ColorSettingView
            bg
                .ignoresSafeArea()
            VStack {
                
                Button("Show\n\(bg.description)") {
                    colorSetting = true
                }
                .sheet(isPresented: $colorSetting, content: {
                    ColorSettingView(bgColor: $bg)}
                )
                
            }
        }
    }
}

Hi, Claude31.

Thank you for your prompt reply. I tried your code. Finally It worked! I am grateful for your support!

How do I change another View's background color as same as ColorSettingView?
 
 
Q