我成功地将 environmentObject appSettings 传递到我的视图中。我可以用它来修改我的字体和视图中的选择器。但是,如果我尝试在视图 init() 中访问 environmentObject 发布的变量,它会崩溃:
Thread 1: Fatal error: No ObservableObject of type AppSettings found.
A View.environmentObject(_:) for AppSettings may be missing as an ancestor of this view.
Run Code Online (Sandbox Code Playgroud)
在自定义 SwiftUI 视图初始值设定项中使用 environmentObject 是否有特殊规则?
这是我的视图代码的开始。environmentObject 是 appSettings。如果我在初始化程序中注释掉第 2 行并取消注释第 3 行,应用程序就可以运行。请注意,我稍后在我的选择器中成功使用了“appSettings.interfaces”。
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)
}
}
Run Code Online (Sandbox Code Playgroud)
这是我在 AppDelegate.swift 中创建顶级内容视图的地方
let contentView = ContentView(showCapture: true).environmentObject(appSettings)
Run Code Online (Sandbox Code Playgroud)
并且只是为了确保在我的顶级 ContentView 中创建我的 CaptureFilterView 时我也传递了 environmentObject。这不是必需的,也不会改变行为。
if showCapture { CaptureFilterView(frames: self.$frames).environmentObject(appSettings) }
Run Code Online (Sandbox Code Playgroud)
作为参考,这里是我的 appSettings 的顶部:
class AppSettings: ObservableObject {
@Published var font: Font
@Published var interfaces: [String]
Run Code Online (Sandbox Code Playgroud)
SwiftUI EnvironmentObject 在视图初始值设定项中不可用?
是的,SwiftUI EnvironmentObject 在 View 初始值设定项中不可用。为什么?这很简单 - 它在对象初始化之后注入。
让我们考虑一下上面的例子是如何完成的ContentView:
let contentView = ContentView(showCapture: true).environmentObject(appSettings)
Run Code Online (Sandbox Code Playgroud)
那么这里发生了什么?这里
1) ContentView 类型的值的实例化和初始化
let newInstance = ContentView.init(showCapture: true)
Run Code Online (Sandbox Code Playgroud)
2)func environmentObject()在newInstance注入的appSetting属性上调用函数
let contentView = newInstance.environmentObject(appSettings)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
565 次 |
| 最近记录: |