如何解决将数据从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 举报,一经查实,本站将立刻删除。