Swift & SwiftUI
  • İçerikler
  • UI Bileşenleri
    • Text
    • Button
    • Image
    • Picker
    • SecureField
    • Stepper
    • Slider
    • TabView
    • Sheet
    • Action Sheet
    • Alert
  • Layout
    • Fill-Space-Equally
  • State & Data Flow
    • Content
    • EnvironmentObject
    • ObservableObject
    • ObservedObject
    • Binding
  • Gestures
    • TapGesture
    • DragGesture
    • MagnificationGesture
    • RotationGesture
    • LongPressGesture
    • Notes
  • Extra
    • GeometryReader
    • Timer
    • AlignmentGuide
    • PreferenceKey
  • Concurrency
    • Perform asynchronous operation
Powered by GitBook
On this page

Was this helpful?

  1. State & Data Flow

EnvironmentObject

A linked View property that reads a `ObservableObject` supplied by an ancestor view that will automatically invalidate its view when the object changes.

State Management

Share Data between Views using @EnvironmentObject

class User: ObservableObject {
    @Published var name = "Enes Karaosman"
}

// View 1
struct EditView: View {
    @EnvironmentObject var user: User
    
    var body: some View {
        TextField("Name", text: $user.name)
    }
}

// View 2
struct DisplayView: View {
    @EnvironmentObject var user: User
    
    var body: some View {
        Text(user.name)
    }
}

// Container View to demonstrate communication
struct DemoView: View {
    let user = User()
    
    var body: some View {
        VStack {
            EditView()//.environmentObject(user)
            DisplayView()//.environmentObject(user)
        }
        // Since both views wrapped by same container
        // We can bind here as well.
        .environmentObject(user)
    }
}

EnvironmentObject does not require to be passed explicitly down to child views.

// Lets demonstrate the information above

// Dummy class for testing EnvironmentObject
class EnvTest: ObservableObject {
    @Published var testStr = "inital"
}

// In SceneDelegate, add those
let envTest = EnvTest()
let contentView = ContentView() // Assume ContentView is initial View
    .environmentObject(envTest)
    
struct ContentView: View {

    // Now we are able to read environmentObject 
    // passed from SceneDelegate, could be anywhere
    @EnvironmentObject() var envTest: EnvTest
    
    var body: some View {
        VStack(spacing: 16) {
            
            Text("Main")
            TextField("Placeholder", text: $envTest.testStr)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            
            Rectangle().foregroundColor(.red).frame(height: 2)
            Child1() // Dummy Child View 
                
        }.padding()
    }
    
}

Lets also create 2 dummy child view.

struct Child1: View {
    
    @EnvironmentObject var envTest: EnvTest
    
    var body: some View {
        VStack {
            Text("Child 1").font(.headline)
            Text(envTest.testStr)
            Rectangle().foregroundColor(.blue).frame(height: 2)
            Child2()
        }
    }
    
}


struct Child2: View {
    
    @EnvironmentObject() var envTest: EnvTest
    
    var body: some View {
        VStack {
            Text("Child 2").font(.headline)
            TextField("Placeholder", text: $envTest.testStr)
                .textFieldStyle(RoundedBorderTextFieldStyle())
        }
    }
    
}

Now when we edit envTest (EnvironmentObject) in any child, the changes reflected everywhere it is used.

PreviousContentNextObservableObject

Last updated 5 years ago

Was this helpful?

EnvironmentObject across child views