【问题标题】:SwiftUI UIViewRepresentable and Custom DelegateSwiftUI UIViewRepresentable 和自定义委托
【发布时间】:2020-03-23 10:57:35
【问题描述】:

在为 SwiftUI 创建 UIViewControllerRepresentable 时,如何创建 Coordinator 以便它可以访问第三方库的委托?

在这种情况下,我正在尝试访问BBMetal,这是一个照片过滤库。

这是我们试图“桥接”到 SwiftUI 的代码的截断版本:

class CameraPhotoFilterVC: UIViewController {
    private var camera: BBMetalCamera!
    private var metalView: BBMetalView!
    private var faceView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        ...

    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        camera.start()
    }...
}

extension CameraPhotoFilterVC: BBMetalCameraPhotoDelegate {
    func camera(_ camera: BBMetalCamera, didOutput texture: MTLTexture) {
        // do something with the photo
    }

    func camera(_ camera: BBMetalCamera, didFail error: Error) {
        // In main thread
        print("Fail taking photo. Error: \(error)")
    }
}

使用 UIViewRepresentable 一切设置正确,CameraPhotoFilterVC 工作,启动相机等,但扩展没有响应。我们尝试将其设置为协调器:

func makeCoordinator() -> Coordinator {
 Coordinator(self)
}

func makeUIViewController(context: UIViewControllerRepresentableContext<CameraPreviewView>) -> CameraViewController {
 let cameraViewController = CameraViewController()
 // Throws an error because what we really want is a BBMetalCameraPhotoDelegate
 //cameraViewController.delegate = context.coordinator
 return cameraViewController
}

class Coordinator: NSObject, BBMetalCameraPhotoDelegate {
 var parent: CameraPreviewView
 init(_ parent: CameraPreviewView) {
  self.parent = parent
 }

 func camera(_ camera: BBMetalCamera, didOutput texture: MTLTexture) {
  print("do something with the photo")
 }
 func camera(_ camera: BBMetalCamera, didFail error: Error) {
  print("Fail taking photo. Error: \(error)")
 }
}

我们也尝试过简单地保留 ViewController 的扩展:

final class CameraViewController : UIViewController  {
...
}

extension CameraViewController: BBMetalCameraPhotoDelegate {
   func camera(_ camera: BBMetalCamera, didOutput texture: MTLTexture) {
        ...
}

但是,来自 BBMetalCameraPhotoDelegate 的委托方法不会“触发”。

我想问题是:在 UIViewControllerRepresentable 或 UIViewRepresentable 中,如何在 makeUIViewController 方法中添加“外部”委托?

通常,如果这是一个 UIPickerView,下面的行会起作用:

picker.delegate = context.coordinator

但在这种情况下,委托是“一旦被移除”

【问题讨论】:

  • 为什么不在viewDidLoad 中设置camera.delegate = self
  • 哇,谢谢你的回答。这不完全是问题,但它引发了关于检查什么的想法。在这种情况下,问题在于第三方库没有将其称为委托 - 它称为 photoDelegate。所以我所做的所有尝试都会返回错误。通过在 viewDidLoad 中添加 camera.photoDelegate = self 就可以了!谢谢。
  • 顺便说一句,没有复选标记可以作为正确答案,但如果可以的话,我会的!

标签: swift swiftui


【解决方案1】:

您需要在使用 BBMetalCamera 之前的某个时间点设置它。

您可以在创建后立即执行此操作。你没有展示你是如何创建它的,所以我不知道这是否是一个设置它的好地方。

您可以在viewDidLoad 中进行操作:

override func viewDidLoad() {
    super.viewDidLoad()

    camera.photoDelegate = self
}

【讨论】:

    猜你喜欢
    • 2020-10-09
    • 2021-09-30
    • 2020-09-29
    • 2020-01-28
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    相关资源
    最近更新 更多