将数据从ViewController传递到SwiftUI View

问题描述

每次如何将数据从最新的 ViewController 传递到 SwiftUI View

问题: 所以实际上我可以传递数据,但是我对数据的更新有疑问。

我想在我的SwiftUI项目中与UIKit接口,该项目需要使用后置摄像头来创建拾色器。 存储Color的变量每次在ViewController中更新时,但是当我想通过ViewControllerWrapper将其数据传递到ContentView中时,在我关闭并重新打开我的应用程序时,变量的值就是update。

我的实际工作:

内容视图:

struct ContentView: View {
    
    @State var color: UIColor = UIColor.clear

    var body: some View {
        ZStack{
            Color("c2").edgesIgnoringSafeArea(.all)
            NavigationView{
                vstack{
                    Cameraview(color: $color)
                    DockView(color: $color)
                }
                .navigationViewStyle(StackNavigationViewStyle())
                .navigationBarTitle("",displayMode: .inline)
                .navigationBarItems(trailing: Image(systemName: "circle.grid.hex").font(.system(size: 28)).foregroundColor(Color("c1")))
            
            }
        }
    }
}

(Cameraview)视图控制器:

struct Cameraview: View {
    
    @Binding var color: UIColor


    var body: some View {
        ViewControllerWrapper(color: $color)
    }
}

struct ViewControllerWrapper: UIViewControllerRepresentable {
    typealias UIViewControllerType = ViewController
    
    @Binding var color: UIColor
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<ViewControllerWrapper>) -> ViewController {
        let v = ViewController()
        return v
    }

    func updateUIViewController(_ uiViewController: ViewController,context: UIViewControllerRepresentableContext<ViewControllerWrapper>) {
        color = uiViewController.color
    }

}

class ViewController: UIViewController,AVCaptureVideoDataOutputSampleBufferDelegate {
    
    
    let captureSession = AVCaptureSession()
    var currentDevice: AVCaptureDevice?
    var center: CGPoint = CGPoint(x: WIDTH/2-4,y:WIDTH/2-4)
    
    var color: UIColor = UIColor.clear
    
    func captureOutput(_ output: AVCaptureOutput,didOutput sampleBuffer: CMSampleBuffer,from connection: AVCaptureConnection) {
        guard let imageBuffer = CMSampleBufferGetimageBuffer(sampleBuffer) else {
            return
        }
        CVPixelBufferLockBaseAddress(imageBuffer,CVPixelBufferLockFlags(rawValue: CVOptionFlags(0)))
        guard let baseAddr = CVPixelBufferGetBaseAddressOfPlane(imageBuffer,0) else {
            return
        }
        let width = CVPixelBufferGetWidthOfPlane(imageBuffer,0)
        let height = CVPixelBufferGetHeightOfPlane(imageBuffer,0)
        let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer,0)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bimapInfo: CGBitmapInfo = [
            .byteOrder32Little,CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)]
        
        guard let content = CGContext(data: baseAddr,width: width,height: height,bitsPerComponent: 8,bytesPerRow: bytesPerRow,space: colorSpace,bitmapInfo: bimapInfo.rawValue) else {
            return
        }
        
        guard let cgImage = content.makeImage() else {
            return
        }
        
        dispatchQueue.main.async {
            self.previewLayer.contents = cgImage
            
            self.color = self.previewLayer.pickColor(at: self.center)!
            
            self.previewLayer.frame = self.view.frame
            self.lineshape.strokeColor = self.color.cgColor
            self.lineshape2.fillColor = self.color.cgColor
            self.label.text = "#\(self.hexFromUIColor(color: self.color))"
        }
        
    }
    
    let previewLayer = CALayer()
    let lineshape = CAShapeLayer()
    let lineshape1 = CAShapeLayer()
    let lineshape2 = CAShapeLayer()
    let lineshape3 = CAShapeLayer()
    let label = UILabel()
    
    func setupUI() {
        previewLayer.frame = view.frame
        
        
        previewLayer.contentsGravity = CALayerContentsGravity.resizeAspectFill
        previewLayer.masksToBounds = true
        previewLayer.setAffineTransform(CGAffineTransform(rotationAngle: CGFloat(.pi / 2.0)))
        view.layer.insertSublayer(previewLayer,at: 0)
        
        //Cercle
        let linePath = UIBezierPath.init(ovalIn: CGRect.init(x: 0,y: 0,width: 40,height: 40))
        lineshape.frame = CGRect.init(x: WIDTH/2-20,y:WIDTH/2-20,height: 40)
        lineshape.linewidth = 5
        lineshape.strokeColor = UIColor.red.cgColor
        lineshape.path = linePath.cgPath
        lineshape.fillColor = UIColor.clear.cgColor
        self.view.layer.insertSublayer(lineshape,at: 1)
        
        //Point
        let linePath1 = UIBezierPath.init(ovalIn: CGRect.init(x: 0,width: 8,height: 8))
        lineshape1.frame = CGRect.init(x: WIDTH/2-4,y:WIDTH/2-4,height: 8)
        lineshape1.path = linePath1.cgPath
        lineshape1.fillColor = UIColor.init(white: 0.7,alpha: 0.5).cgColor
        self.view.layer.insertSublayer(lineshape1,at: 1)
        
        //Preview
        let linePath2 = UIBezierPath.init(ovalIn: CGRect.init(x: 0,width: 25,height: 25))
        lineshape2.frame = CGRect.init(x: WIDTH/2-70,y:120,height: 25)
        lineshape2.path = linePath2.cgPath
        lineshape2.fillColor = UIColor.clear.cgColor
        self.view.layer.insertSublayer(lineshape2,at: 1)
        
        //Container
        let linePath3 = UIBezierPath.init(roundedRect: CGRect.init(x: 0,width: 150,height: 50),cornerRadius: 25)
        lineshape3.frame = CGRect.init(x: WIDTH/2-80,y:107,height: 30)
        lineshape3.path = linePath3.cgPath
        lineshape3.fillColor = UIColor(named: "c3")?.cgColor
        self.view.layer.insertSublayer(lineshape3,at: 1)
        
        
        //Label
        label.frame = CGRect.init(x: WIDTH/2-35,width: 100,height: 21)
        label.font = UIFont.systemFont(ofSize: 20,weight: UIFont.Weight.semibold)
        label.tintColor = UIColor(named: "c1")
        self.view.addSubview(label)
        
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        self.CreateUI()
    }
    
  
    
    let queue = dispatchQueue(label: "com.camera.video.queue")
    
    
    func CreateUI(){
        self.captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080

        self.currentDevice = AVCaptureDevice.default(.builtInWideAngleCamera,for: AVMediaType.video,position: .back)
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!)
            let videoOutput = AVCaptureVideoDataOutput()
            videoOutput.videoSettings = ([kCVPixelBufferPixelFormatTypeKey as AnyHashable: NSNumber(value: kCMPixelFormat_32BGRA)] as! [String : Any])
            videoOutput.alwaysdiscardsLateVideoFrames = true
            videoOutput.setSampleBufferDelegate(self,queue: queue)
            
            if self.captureSession.canAddOutput(videoOutput) {
                self.captureSession.addOutput(videoOutput)
            }
            self.captureSession.addInput(captureDeviceInput)
        } catch {
            print(error)
            return
        }
            self.captureSession.startRunning()
    }
    func hexFromUIColor(color: UIColor) -> String{
        let hexString = String(format: "%02X%02X%02X",Int(color.cgColor.components![0]*255.0),Int(color.cgColor.components![1]*255.0),Int(color.cgColor.components![2]*255.0))
        return hexString
    }
    
    
}

如果您知道如何在我的ContentView中获取数据的价值。

谢谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)