SwiftUI EnvironmentObject not available in View initializer?

前提是你 提交于 2021-01-28 03:06:48

问题


I passed the environmentObject appSettings into my view successfully. I can use it to modify my font and the picker in my View. But if I try to access an environmentObject published variable in the view init() it crashes with:

Thread 1: Fatal error: No ObservableObject of type AppSettings found.
A View.environmentObject(_:) for AppSettings may be missing as an ancestor of this view.

Are there special rules about using an environmentObject in a custom SwiftUI View initializer?

Here's the start of my view code. The environmentObject is appSettings. If I comment out line 2 in my initializer and uncomment line 3 the app works. Note that I use "appSettings.interfaces" successfully later in my Picker.

struct CaptureFilterView: View {

@State var etherCapture: EtherCapture? = nil
@EnvironmentObject var appSettings: AppSettings
@Binding var frames: [Frame]
@State var captureFilter: String = ""
@State var error: String = ""
@State var numberPackets = 10

@State var interface: String = ""
init(frames: Binding<[Frame]>) {
    self._frames = frames
    self.interface = appSettings.interfaces.first ?? "en0" //CRASH HERE
    //self.interface = "en0"  //uncomment this and comment line above to make app "work"
}
var body: some View {
    HStack() {
        ...
        Picker(selection: $interface, label: Text("")) {
            ForEach(appSettings.interfaces, id: \.self) { interfaceName in
                Text(interfaceName).tag(interfaceName)
            }
        }

Here's where I create my top-level content view in my AppDelegate.swift

        let contentView = ContentView(showCapture: true).environmentObject(appSettings)

And just to be sure I also pass on the environmentObject when creating my CaptureFilterView in my top level ContentView. This is not necessary and does not change the behavior.

            if showCapture { CaptureFilterView(frames: self.$frames).environmentObject(appSettings) }

For reference here is the top of my appSettings:

class AppSettings: ObservableObject {
    @Published var font: Font
    @Published var interfaces: [String]

回答1:


SwiftUI EnvironmentObject not available in View initializer?

Yes, SwiftUI EnvironmentObject not available in View initializer. Why? It is simple - it is injected after object initialiazation.

Let's consider how it is done on example of above ContentView:

let contentView = ContentView(showCapture: true).environmentObject(appSettings)

so what's going on here? Here

1) instantiation & initialisation of value for the type ContentView

let newInstance = ContentView.init(showCapture: true) 

2) calling function func environmentObject() on newInstance injected appSetting property

let contentView = newInstance.environmentObject(appSettings)


来源:https://stackoverflow.com/questions/60514448/swiftui-environmentobject-not-available-in-view-initializer

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!