gpt4 book ai didi

ios - 将数据从 ViewController 传递到 Representable SwiftUI

转载 作者:行者123 更新时间:2023-12-04 11:37:42 25 4
gpt4 key购买 nike

我正在做一个物体检测并使用 UIViewControllerRepresentable添加我的 View Controller 。问题是我无法从 ViewController 传递数据到我的 SwiftUI View 。我可以打印它。
有人能帮我吗?这是我的代码:

//

import SwiftUI
import AVKit
import UIKit
import Vision
let SVWidth = UIScreen.main.bounds.width

struct MaskDetectionView: View {
let hasMaskColor = Color.green
let noMaskColor = Color.red
let shadowColor = Color.gray

var body: some View {
VStack(alignment: .center) {
VStack(alignment: .center) {
Text("Please place your head inside the bounded box.")
.font(.system(size: 15, weight: .regular, design: .default))
Text("For better result, show your entire face.")
.font(.system(size: 15, weight: .regular, design: .default))
}.padding(.top, 10)

VStack(alignment: .center) {
SwiftUIViewController()
.frame(width: SVWidth - 30, height: SVWidth + 30, alignment: .center)
.background(Color.white)
.cornerRadius(25)
.shadow(color: hasMaskColor, radius: 7, x: 0, y: 0)
.padding(.top, 30)
Spacer()

/// VALUE HERE
}

}.padding()
}
}

struct MaskDetectionView_Previews: PreviewProvider {
static var previews: some View {
MaskDetectionView()

}
}


class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {


var result = String()
//ALL THE OBJECTS
override func viewDidLoad() {
super.viewDidLoad()

// 1 - start session
let capture_session = AVCaptureSession()
//capture_session.sessionPreset = .vga640x480

// 2 - set the device front & add input
guard let capture_device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: .video, position: .front) else {return}

guard let input = try? AVCaptureDeviceInput(device: capture_device) else { return }
capture_session.addInput(input)

// 3 - the layer on screen that shows the picture
let previewLayer = AVCaptureVideoPreviewLayer(session: capture_session)
view.layer.addSublayer(previewLayer)
previewLayer.frame.size = CGSize(width: SVWidth, height: SVWidth + 40)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

// 4 - run the session
capture_session.startRunning()

// 5 - the produced output aka image or video
let dataOutput = AVCaptureVideoDataOutput()
dataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
capture_session.addOutput(dataOutput)
}

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection){
// our model

guard let model = try? VNCoreMLModel(for: SqueezeNet(configuration: MLModelConfiguration()).model) else { return }
// request for our model
let request = VNCoreMLRequest(model: model) { (finishedReq, err) in
if let error = err {
print("failed to detect faces:", error)
return

}
//result
guard let results = finishedReq.results as? [VNClassificationObservation] else {return}
guard let first_observation = results.first else {return}

self.result = first_observation.identifier
print(self.result)

}

guard let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {return}
try? VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]).perform([request])
}

}






struct SwiftUIViewController: UIViewControllerRepresentable {

func makeUIViewController(context: Context) -> ViewController{
return ViewController()
}

func updateUIViewController(_ uiViewController: ViewController, context: Context) {

}

}




最佳答案

简而言之,您需要传播一个 Binding实例通过 UI 层次结构(这包括 SwiftUI 和 UIKit 代码)。此 Binding将透明地更新连接到它的所有 View 上的数据,无论是谁进行了更改。
数据流图可能类似于:
enter image description here
现在,首先,您需要一个 @State将分类标识符存储在 SwiftUI View 中,以便它可以连接到您的 View Controller ,以及另一个将显示它的 UI 元素:

struct MaskDetectionView: View {
@State var clasificationIdentifier: String = ""
接下来,您需要将其传递给 View Controller 和一些 UI 元素:
var body: some View {
...
SwiftUIViewController(identifier: $clasificationIdentifier)
...
// this is the "VALUE HERE" from your question
Text("Clasification identifier: \(clasificationIdentifier)")
现在,我们正确地注入(inject)了绑定(bind),让我们更新代码的 UIKit 端以允许接收绑定(bind)。
更新您的可表示 View ,使其看起来像这样:
struct SwiftUIViewController: UIViewControllerRepresentable {

// this is the binding that we receive from the SwiftUI side
let identifier: Binding<String>

// this will be the delegate of the view controller, it's role is to allow
// the data transfer from UIKit to SwiftUI
class Coordinator: ViewControllerDelegate {
let identifierBinding: Binding<String>

init(identifierBinding: Binding<String>) {
self.identifierBinding = identifierBinding
}

func clasificationOccured(_ viewController: ViewController, identifier: String) {
// whenever the view controller notifies it's delegate about receiving a new idenfifier
// the line below will propagate the change up to SwiftUI
identifierBinding.wrappedValue = identifier
}
}

func makeUIViewController(context: Context) -> ViewController{
let vc = ViewController()
vc.delegate = context.coordinator
return vc
}

func updateUIViewController(_ uiViewController: ViewController, context: Context) {
// update the controller data, if needed
}

// this is very important, this coordinator will be used in `makeUIViewController`
func makeCoordinator() -> Coordinator {
Coordinator(identifierBinding: identifier)
}
}
最后一块拼图是为 View Controller 委托(delegate)编写代码,以及使用该委托(delegate)的代码:
protocol ViewControllerDelegate: AnyObject {
func clasificationOccured(_ viewController: ViewController, identifier: String)
}

class ViewController: UIViewController {

weak var delegate: ViewControllerDelegate?

...

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
...

print(self.result)

// let's tell the delegate we found a new clasification
// the delegate, aka the Coordinator will then update the Binding
// the Binding will update the State, and this change will be
// propagate to the Text() element from the SwiftUI view
delegate?.clasificationOccured(self, identifier: self.result)
}

关于ios - 将数据从 ViewController 传递到 Representable SwiftUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64959542/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com