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