SwiftUI UIViewRepresentable和自定义委托

时间:2019-11-27 20:08:36

标签: swift swiftui

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

在这种情况下,我尝试访问照片过滤库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

但是在这种情况下,代表被“一次删除”

1 个答案:

答案 0 :(得分:1)

在使用self的委托之前,需要先设置它。

创建后可能会立即执行。您没有显示如何创建它,所以我不知道这是否是设置它的好地方。

您可能只需要在BBMetalCamera中进行操作即可:

viewDidLoad