在macOS10.15.6与Xcode11.6中NSView向SwiftUI传数据遇环境对象错误
解决SwiftUI中
No ObservableObject of type KeyboardInput found错误 嘿,这个错误我太熟了!本质就是你的SwiftUI视图找不到KeyboardInput这个环境对象——说白了就是你没在视图层级的上层把这个对象“递”下去。我给你一步步拆解怎么修复:
1. 先确认KeyboardInput的基础实现没问题
首先得保证你的KeyboardInput类正确遵循了ObservableObject协议,并且用@Published标记了需要被监听的属性,比如:
import SwiftUI import Combine class KeyboardInput: ObservableObject { @Published var inputText: String = "" // 这里放你需要的其他属性和方法 }
要是这一步没做对,后面的注入也白搭。
2. 在视图层级的根节点注入环境对象
你需要在创建SwiftUI视图的“源头”(比如从NSView跳转初始化SwiftUI容器的时候),把KeyboardInput的实例通过environmentObject(_:)传递进去。
举个具体的例子,如果你是用NSHostingController来承载SwiftUI视图的,代码应该这么写:
// 先创建KeyboardInput的实例 let keyboardInputInstance = KeyboardInput() // 初始化你的SwiftUI视图,同时把实例注入环境 let targetSwiftUIView = YourTargetSwiftUIView().environmentObject(keyboardInputInstance) // 创建NSHostingController并关联这个视图 let hostingController = NSHostingController(rootView: targetSwiftUIView) // 最后把这个hostingController加到你的NSView层级里就行
关键是要在所有需要用到这个对象的子视图的祖先节点上注入,不能在子视图内部才做这件事。
3. 在子视图里正确引用环境对象
在需要使用KeyboardInput的SwiftUI子视图中,一定要用@EnvironmentObject来声明,绝对不能自己在视图里初始化新的实例,比如:
struct YourTargetSwiftUIView: View { // 用@EnvironmentObject声明,让SwiftUI自动从环境中取实例 @EnvironmentObject var keyboardInput: KeyboardInput var body: some View { // 这里就能直接用keyboardInput的属性了 TextField("输入内容", text: $keyboardInput.inputText) } }
最后提醒几个容易踩的坑
- 别在子视图里写
let keyboardInput = KeyboardInput(),这会创建一个全新的实例,和你上层注入的完全不是同一个,自然找不到 - 确保注入环境对象的位置足够“高”,比如如果是整个App用,就在App结构体的根视图注入;如果是某个NSView跳转的子页面,就在那个页面的根视图注入
- 如果你是在Xcode预览里测试,别忘了在预览代码里也加上
environmentObject,不然预览也会报同样的错
内容的提问来源于stack exchange,提问作者kali mera
相关产品推荐
相关产品推荐

