How to bind environment variable ios17
Asked Answered
V

2

6

With the new @Observable macro introduced for iOS 17, we can now use environment objects in the following way

@Environment(MyType.self) var myTypeObj

Now if myTypeObj has some property, call it myProperty which I'd like to pass as binding somewhere using $ syntax, Swift complains that it cannot find the variable. For example,

Picker("My Picker", selection: $myTypeObj.myProperty) { // we get an error on this line
  ForEach(1 ... 50, id: \.self) { num in
    ...
  }
}

we get an error saying Cannot find $myTypeObj in scope. Is this a Swift bug or am I doing something wrong?

Visual answered 23/8, 2023 at 3:37 Comment(0)
D
11

In iOS 17 you have to use Bindable.

@Observable
class AppState {
    var isOn: Bool = false
}

struct ContentView: View {
    
    @Environment(AppState.self) private var appState
    
    var body: some View {
        
        @Bindable var bindable = appState
        
        VStack {
            Toggle("Is On", isOn: $bindable.isOn)
        }
        .padding()
    }
}

#Preview {
    ContentView()
        .environment(AppState())
}

in main App:

import SwiftUI

@main
struct myApp: App {

    private var appState = AppState()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(appState)

        }
    }
}
Deventer answered 23/8, 2023 at 3:53 Comment(0)
L
1

To myself and others I also think azamsharp in his video enter link description here mentioned for Binding to work we have to use a separate view to bind to. But here we can see that there are another way:

  1. @Environment(AppState.self) private var appState
  2. @Bindable var bindable = appState but most important :this @Bindable is placed in "body View"
Luminesce answered 23/10, 2023 at 9:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.