Ios 将数据从ViewController传递到SwiftUI视图

Ios 将数据从ViewController传递到SwiftUI视图,ios,swift,swiftui,uikit,Ios,Swift,Swiftui,Uikit,如何将数据从ViewController传递到SwiftUI View每次更新 问题: 所以实际上我可以传递数据,但我在数据更新方面有问题 我想在我的SwiftUI项目中与UIKit接口,该项目需要使用后置摄像头创建颜色选择器。 存储颜色的变量在我的ViewController中每次都会更新,但当我想通过ViewControllerRapper在ContentView中传递此数据时,该变量的值在我关闭并打开我的应用程序时会更新 我的实际工作: 内容视图: (CameraView)查看控制器: s

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

问题: 所以实际上我可以传递数据,但我在数据更新方面有问题

我想在我的SwiftUI项目中与UIKit接口,该项目需要使用后置摄像头创建颜色选择器。 存储颜色的变量在我的ViewController中每次都会更新,但当我想通过ViewControllerRapper在ContentView中传递此数据时,该变量的值在我关闭并打开我的应用程序时会更新

我的实际工作:

内容视图:

(CameraView)查看控制器:

struct-CameraView:视图{
@绑定变量颜色:UIColor
var body:一些观点{
ViewControllerRapper(颜色:$color)
}
}
结构ViewControllerRapper:UIViewControllerRepresentable{
typealias UIViewControllerType=ViewController
@绑定变量颜色:UIColor
func makeUIViewController(上下文:UIViewControllerRepresentableContext)->ViewController{
设v=ViewController()
返回v
}
func updateUIViewController(uUIViewController:ViewController,上下文:UIViewControllerRepresentableContext){
color=uiViewController.color
}
}
类ViewController:UIViewController、AVCaptureVideoDataOutputSampleBufferDelegate{
让captureSession=AVCaptureSession()
var currentDevice:AVCaptureDevice?
变量中心:CGPoint=CGPoint(x:WIDTH/2-4,y:WIDTH/2-4)
变量颜色:UIColor=UIColor.clear
func captureOutput(\uOutput:AVCaptureOutput,didOutput sampleBuffer:CMSampleBuffer,from connection:AVCaptureConnection){
guard let imageBuffer=CMSampleBufferGetImageBuffer(sampleBuffer)else{
返回
}
CVPixelBufferLockBaseAddress(imageBuffer,CVPixelBufferLockFlags(rawValue:CVOptionFlags(0)))
guard let baseAddr=CVPixelBufferGetBaseAddressOfPlane(imageBuffer,0)else{
返回
}
let width=CVPixelBufferGetWidthOfPlane(imageBuffer,0)
let height=CVPixelBufferGetHeightof平面(imageBuffer,0)
让bytesPerRow=CVPixelBufferGetBytesPerrowOffPlane(imageBuffer,0)
让colorSpace=CGColorSpaceCreateDeviceRGB()
设bimapInfo:CGBitmapInfo=[
.ByteLittle,
CGBitmapInfo(rawValue:CGImageAlphaInfo.premultipledfirst.rawValue)]
guard let content=CGContext(数据:baseAddr,宽度:宽度,高度:高度,bitsPerComponent:8,bytesPerRow:bytesPerRow,空格:colorSpace,bitmapInfo:bimapInfo.rawValue)其他{
返回
}
guard let cgImage=content.makeImage()else{
返回
}
DispatchQueue.main.async{
self.previewLayer.contents=cgImage
self.color=self.previewLayer.pickColor(位于: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))”
}
}
让previewLayer=CALayer()
设lineShape=CAShapeLayer()
设lineShape1=CAShapeLayer()
设lineShape2=CAShapeLayer()
设lineShape3=CAShapeLayer()
let label=UILabel()
func setupUI(){
previewLayer.frame=view.frame
previewLayer.contentsGravity=CALayerContentsGravity.resizeAspectFill
previewLayer.masksToBounds=true
previewLayer.setAffineTransform(CGAffineTransform(旋转角度:CGFloat(.pi/2.0)))
view.layer.insertSublayer(预览层,位于:0)
//蜡
设linePath=UIBezierPath.init(ovalIn:CGRect.init(x:0,y:0,宽度:40,高度:40))
lineShape.frame=CGRect.init(x:WIDTH/2-20,y:WIDTH/2-20,WIDTH:40,height:40)
lineShape.lineWidth=5
lineShape.strokeColor=UIColor.red.cgColor
lineShape.path=linePath.cgPath
lineShape.fillColor=UIColor.clear.cgColor
self.view.layer.insertSublayer(线型,at:1)
//点
让linePath1=UIBezierPath.init(ovalIn:CGRect.init(x:0,y:0,宽度:8,高度:8))
lineShape1.frame=CGRect.init(x:WIDTH/2-4,y:WIDTH/2-4,WIDTH:8,height:8)
lineShape1.path=linePath1.cgPath
lineShape1.fillColor=UIColor.init(白色:0.7,alpha:0.5).cgColor
self.view.layer.insertSublayer(lineShape1,at:1)
//预演
设linePath2=UIBezierPath.init(ovalIn:CGRect.init(x:0,y:0,宽度:25,高度:25))
lineShape2.frame=CGRect.init(x:WIDTH/2-70,y:120,WIDTH:25,height:25)
lineShape2.path=linePath2.cgPath
lineShape2.fillColor=UIColor.clear.cgColor
self.view.layer.insertSublayer(lineShape2,at:1)
//容器
让linePath3=UIBezierPath.init(roundedRect:CGRect.init(x:0,y:0,宽度:150,高度:50),拐角半径:25)
lineShape3.frame=CGRect.init(x:WIDTH/2-80,y:107,WIDTH:150,height:30)
lineShape3.path=linePath3.cgPath
lineShape3.fillColor=UIColor(名称:“c3”)?.cgColor
self.view.layer.insertSublayer(lineShape3,at:1)
//标签
label.frame=CGRect.init(x:WIDTH/2-35,y:120,WIDTH:100,height:21)
label.font=UIFont.systemFont(尺寸:20,重量:UIFont.weight.semibold)
label.tintColor=UIColor(命名为:“c1”)
self.view.addSubview(标签)
}
重写func viewDidLoad(){
super.viewDidLoad()
setupUI()
self.CreateUI()
}
let queue=DispatchQueue(标签:“com.camera.video.queue”)
创建函数
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")))
            
            }
        }
    }
}
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, width: 40, 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, y: 0, width: 8, height: 8))
        lineShape1.frame = CGRect.init(x: WIDTH/2-4, y:WIDTH/2-4, width: 8, 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, y: 0, width: 25, height: 25))
        lineShape2.frame = CGRect.init(x: WIDTH/2-70, y:120, width: 25, 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, y: 0, width: 150, height: 50), cornerRadius: 25)
        lineShape3.frame = CGRect.init(x: WIDTH/2-80, y:107, width: 150, 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, y:120, 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
    }
    
    
}