I'm trying to use an @EnvironmentObject to pass data to my SwiftUI view:
struct MyView: View {
@EnvironmentObject var myInt: Int // ❌ Property type 'Int' does not match that of the 'wrappedValue' property of its wrapper type 'EnvironmentObject'
var body: some View {
EmptyView()
}
}
func constructView() {
let myInt = 1
MyView()
.environmentObject(myInt)
}
The line with @EnvironmentObject had a compiler error (listed above).
How do I use @EnvironmentObject
with an Int
?
Update: One thought was that @EnvironmentObject
can only be used with classes that conform to ObservableObject
, so I tried switching to @Environment
which now that part compiled, but produced a different error:
struct MyView: View {
@Environment var myInt: Int
var body: some View {
EmptyView()
}
}
func constructView() {
let myInt = 1
MyView() // ❌ Missing argument for parameter 'myInt' in call
.environment(\.myInt, myInt)
}
Now when I attempt to construct it, it complains that myInt
isn't set.
@EnvironmentObject
can only be used with a class
. Int
is actually a struct
.
If you did want to try to share that Int
between View
s, you could wrap the value in a class:
class SharedInt: ObservableObject {
@Published var myInt = 1
}
Also, it should look more like this inside SceneDelegate.swift
:
let contentView = ContentView().environmentObject(SharedInt())
if let windowScene = /* ... */
Or in SwiftUI lifecycle's ...App.swift
:
WindowGroup {
ContentView()
.environmentObject(SharedInt())
}
If you want to use the environment system, you need to provide a key to access it. You can't use an unregistered key (which is what your error is). First, create an EnvironmentKey
:
struct MyIntEnvironmentKey: EnvironmentKey {
static var defaultValue = 0
}
Next, create a key path to set/get your environment value:
extension EnvironmentValues {
var myInt: Int {
get { self[MyIntEnvironmentKey.self] }
set { self[MyIntEnvironmentKey.self] = newValue }
}
}
Now, you can set it in your parent View:
MyView().environment(\.myInt, myInt)
And crucially, you need to reference the key in the view in which you want to reference it:
struct MyView: View {
@Environment(\.myInt) private var myInt: Int
var body: some View {
Text("\(self.myInt)")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With