swift - SwiftUI 中的非 View 子类是否可以访问 environmentObject

标签 swift swiftui

我了解 EnvironmentObjects 用于在 View 之间共享数据。
我很想知道其他非 View 子类是否可以访问 EnvironmentObjects 并更新它们。
如果是,我们是否在这里打破了任何架构模式?
如果我们需要访问非 View 子类中的 EnvironmentObjects,我们应该采取什么方法

编辑-I

我正在使用 AVFoundation 来获取视频帧。收到帧后,我尝试更新 environmentObject 以便所有 View 都可以访问该帧。下面是代码:

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()
}

在其中一个 View 中创建 Coordinator 对象

最佳答案

EnvironmentObject只是一种注入(inject)引用类型实例的机制,以确认 ObservableObject协议(protocol)到 SwiftUI View 层次结构中,如果相应的属性发生变化,只需观察相应的发布者即可更新此类 View 。但它只是普通的引用类型实例,你可以像传递任何其他引用类型实例一样在这里和那里传递它,并像处理任何其他引用类型实例一样使用它(属性、函数)。

没有魔法。

更新:现在开始编码

您不需要使用 @EnvironmentObject您的委托(delegate)中的包装器用于 View ,而不是使用以下内容(粗糙,因为您的代码剪切)

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
    }
    ...

关于swift - SwiftUI 中的非 View 子类是否可以访问 environmentObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61291889/

相关文章:

ios - Apple Watch 不显示任何图像

SwiftUI:在编辑开始时清除 TextField

iOS SwiftUI 视频自动播放

arrays - 如何创建不重复的子数组 Swift

swift - 如何使 SwiftUI 选择器自动换行

快速组合 : Merge publishers of different types

ios - 无法在 Collection View 中选择项目,Swift

IOS- swift : OrPredicate in CloudKit results in invalid

swift - 如何在启用分页的情况下水平居中 UICollectionViewCells? ( swift )

ios - Model View Presenter 和 iOS (Swift) 架构