swift - SwiftUI 中的非 View 子类是否可以访问 environmentObject
问题描述
我了解 EnvironmentObjects 用于在视图之间共享数据。我很想知道其他非 View 子类是否可以访问 EnvironmentObjects 并更新它们。如果是,我们是否在这里打破了任何架构模式?
如果我们需要访问非 View 子类中的 EnvironmentObjects,我们应该采取什么方法
编辑-I
我正在使用 AVFoundation 来获取视频帧。收到框架后,我尝试更新 environmentObject 以便所有视图都可以访问框架。下面是代码:
class Coordinator {
let delegate = VideoDelegate()
let controller: CameraController!
init(){
controller = CameraController(delegate)
}
}
final class VideoDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate{
@EnvironmentObject var frame: CIImageFrame
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
if let cvImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
self.frame.image = CIImage(cvImageBuffer: cvImageBuffer)
} else {
//Log message
print("CMSampleBuffer to CIImage conversion error")
}
}
}
//Wrap CIImage to make it EnvironmentObject
final class CIImageFrame: ObservableObject {
@Published var image = CIImage()
}
在其中一个视图中创建 Coordinator 对象
解决方案
这EnvironmentObject
只是一种将确认ObservableObject
协议的引用类型实例注入 SwiftUI 视图层次结构并在相应属性发生更改时更新此类视图的机制,只需观察相应的发布者即可。但它只是普通的引用类型实例,你可以像传递任何其他引用类型实例一样在这里和那里传递它,并像处理任何其他引用类型实例一样使用它(属性、函数)。
没有魔法。
更新:现在开始编码
您不需要@EnvironmentObject
在您的委托中使用包装器,它用于视图,而是使用以下内容(scratchy,因为您的代码剪切)
class Coordinator {
let owner: _Owner_Type_ // << here is owner view of coordinator
let delegate: VideoDelegate
let controller: CameraController!
init(owner: _Owner_Type_){
self.owner = owner
// owner is view which has @EnvironmentObject property,
// so use it here to pass into VideoDelegate
delegate = VideoDelegate(frame: owner.frame)
controller = CameraController(delegate)
}
}
final class VideoDelegate: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate{
private var frame: CIImageFrame // just reference member
// now your delegate has reference to the same instance as environment
// object in view
init(frame: CIImageFrame) {
self.frame = frame
}
...
推荐阅读
- java - 通过 ASM 注入 try/catch 块以在字节码中进行可序列化检查
- google-cloud-platform - 如何自动备份和版本存储过程等 BigQuery 代码?
- c# - 有没有办法将同步融合的 SFAutoComplete 扩展到多行?
- python - 用户死亡后如何让游戏循环回到开头
- r - 在向量上循环过滤数据并绑定数据帧
- elasticsearch - 在执行批量索引时,ElasticSearch 是否允许批量级别的版本控制?
- cryptoapi - 如何从 Coin Market Cap API 获取当天 OHLCV 每小时 dta?
- c++ - 切割流、nTuples 和 miniNtuples?
- android - 如何在 Firebase 中将电话与电子邮件和密码身份验证相关联?
- android - Xamarin - 图像加载后,图像下方的内容会消失,直到设备旋转