【发布时间】: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 就可以了!谢谢。
-
顺便说一句,没有复选标记可以作为正确答案,但如果可以的话,我会的!