मैं समझता हूं कि EnvironmentObjects दृश्यों के बीच डेटा साझा करने के लिए हैं। मैं यह जानने के लिए उत्सुक हूं कि क्या अन्य गैर-दृश्य उप-वर्गों के लिए EnvironmentObjects तक पहुंचना और उन्हें अपडेट करना संभव है। यदि हाँ, तो क्या हम यहाँ कोई वास्तु प्रतिमान तोड़ रहे हैं?
यदि हमें गैर-दृश्य उपवर्गों में EnvironmentObjects तक पहुँचने की आवश्यकता है, तो हमारा दृष्टिकोण क्या होना चाहिए

संपादित करें-मैं

मैं वीडियो फ्रेम प्राप्त करने के लिए AVFoundation का उपयोग कर रहा हूं। फ्रेम प्राप्त करने के बाद मैं एक पर्यावरण ऑब्जेक्ट को अपडेट करने का प्रयास कर रहा हूं ताकि सभी दृश्य फ्रेम तक पहुंच सकें। नीचे कोड है:

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

समन्वयक वस्तु विचारों में से एक में बनाई गई है

2
indra 18 अप्रैल 2020, 18:43

2 जवाब

सबसे बढ़िया उत्तर

EnvironmentObject केवल संबंधित प्रकाशकों को देखकर, स्विफ्टयूआई व्यू पदानुक्रम में ObservableObject प्रोटोकॉल की पुष्टि करने वाले संदर्भ प्रकार के उदाहरण को इंजेक्ट करने के लिए एक तंत्र है और यदि संबंधित गुण बदलते हैं तो ऐसे दृश्य को अपडेट करें। लेकिन यह सिर्फ सामान्य संदर्भ प्रकार का उदाहरण है, आप इसे यहां और वहां उसी तरह पास कर सकते हैं जैसे आप किसी अन्य संदर्भ प्रकार के उदाहरण को कैसे पास करते हैं, और इसके साथ (गुण, कार्य) किसी अन्य संदर्भ प्रकार के उदाहरण के साथ काम करते हैं।

कोई जादू नहीं।

अपडेट करें: अभी कोड करने के लिए

आपको अपने प्रतिनिधि में @EnvironmentObject रैपर का उपयोग करने की आवश्यकता नहीं है, यह विचारों के लिए है, इसके बजाय निम्नलिखित का उपयोग करें (खरोंच, आपके कोड कट के रूप में)

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

2
Asperi 18 अप्रैल 2020, 17:11

आप इसे आमतौर पर नॉन-व्यू क्लास के ठेकेदार में पास कर सकते हैं। यहाँ कुछ नमूना कोड है।

import SwiftUI

struct EnvObjContentView: View {
    var body: some View {
        EnvObjMasterView().environmentObject(EnvObjSample())
    }
}
class EnvObjSample: ObservableObject{
    @Published var randomNumber = 0

    func changeRandomNumber() {
        randomNumber = Int.random(in: 0...100)
    }
}
class NonViewClass {
    var eo: EnvObjSample

    init(eo: EnvObjSample){
        self.eo = eo
    }
    func changeRandomNumber() {
        eo.changeRandomNumber()
    }
}
struct EnvObjMasterView: View {
    @EnvironmentObject var eo: EnvObjSample
    @State var nonViewClass: NonViewClass?

    var body: some View {
        VStack{
            Text(eo.randomNumber.description)
            Button(action: {
                if self.nonViewClass != nil{
                    self.nonViewClass!.changeRandomNumber()
                }else{
                   //You can init in other places such as on onAppear()
                    self.nonViewClass = NonViewClass(eo: self.eo)
                    self.nonViewClass!.changeRandomNumber()
                }
            }, label: {
                Text("change-number")
            })
        }
    }
}

struct EnvObjContentView_Previews: PreviewProvider {
    static var previews: some View {
        EnvObjContentView()
    }
}
0
CranialDev 18 अप्रैल 2020, 16:52