SwiftUI UIViewRepresentable 和自定义委托 [英] SwiftUI UIViewRepresentable and Custom Delegate

查看:27
本文介绍了SwiftUI UIViewRepresentable 和自定义委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When creating a UIViewControllerRepresentable for SwiftUI, how do you create a Coordinator so that it can access the delegate of a third party library?

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

In this case, I am trying to access BBMetal, a photo-filtering library.

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

This is a truncated version of the code we are trying to 'bridge' to 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 工作,启动相机等,但扩展没有响应.我们尝试将其设置为协调员:

Using UIViewRepresentable everything sets up properly and the CameraPhotoFilterVC works, starts up the camera, etc, but the extension does not respond. We tried to set this up as a Coordinator:

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 的扩展:

We also tried simply leaving an extension of the ViewController:

final class CameraViewController : UIViewController  {
...
}

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

但是来自 BBMetalCameraPhotoDelegate 的委托方法不会触发".

However the delegate methods from BBMetalCameraPhotoDelegate do not 'fire.

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

I suppose the question is: in UIViewControllerRepresentable or UIViewRepresentable, how do you add an "external" delegate in the makeUIViewController method?

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

Usually, if this was say a UIPickerView, the following line would work:

picker.delegate = context.coordinator

但在这种情况下,委托是一旦删除"

But in this case the delegate is 'once removed'

推荐答案

在使用 BBMetalCamera 之前,您需要在某个时间设置其委托.

You need to set the BBMetalCamera's delegate at some point before you use it.

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

You might do it immediately after creating it. You didn't show how you create it, so I don't know if that would be a good place to set it.

你也许可以在 viewDidLoad 中完成:

You could probably just do it in viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()

    camera.photoDelegate = self
}

这篇关于SwiftUI UIViewRepresentable 和自定义委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆