Swift 使UIViewController符合AVCapturePhotoCaptureDelegate不工作
我正在创建使用照片输出捕捉照片的自定义相机 当用户点击捕获按钮时,调用Swift 使UIViewController符合AVCapturePhotoCaptureDelegate不工作,swift,uiviewcontroller,camera,Swift,Uiviewcontroller,Camera,我正在创建使用照片输出捕捉照片的自定义相机 当用户点击捕获按钮时,调用photoOutput.capturePhoto(with:settings,delegate:self),第二个参数为self表示UIViewController,因为UIViewController符合AVCapturePhotoCaptureDelegate 但是,在实现func photoOutput(uu输出:AVCapturePhotoOutput,didFinishProcessingPhoto-photo:AV
photoOutput.capturePhoto(with:settings,delegate:self)
,第二个参数为self
表示UIViewController
,因为UIViewController
符合AVCapturePhotoCaptureDelegate
但是,在实现func photoOutput(uu输出:AVCapturePhotoOutput,didFinishProcessingPhoto-photo:AVCapturePhoto,error:error?)时会出现一个奇怪的警告,并显示消息-
实例方法“photoOutput(:didFinishProcessingPhoto:error:)”几乎与协议“AVCapturePhotoCaptureDelegate”的可选要求“photoOutput(:didFinishProcessingPhoto:error:)”匹配。
此外,点击带有错误消息的捕获按钮时会发生崩溃-
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[AVCapturePhotoOutput capturePhotoWithSettings:delegate:]如果您在设置中指定非零格式词典,您的代表必须响应选择器captureOutput:didFinishProcessingPhoto:错误:
即使设置的格式字典不是零
但是,当我实现一个符合avcapturepoticapturedelegate
的自定义类时,没有警告,而且运行良好
所以我很好奇。。不应该UIViewController
符合AVCapturePhotoCaptureDelegate
?如果不是,为什么
错误示例:
final class CameraViewController: UIViewController, AVCapturePhotoCaptureDelegate {
...
@IBAction func captureButtonDidTap(_ sender: UIButton) {
guard isSessionRunning else { return }
if let previewLayerOrientation = previewLayer?.connection?.videoOrientation {
let photoOutputConnection = photoOutput?.connection(with: .video)
photoOutputConnection?.videoOrientation = previewLayerOrientation
}
guard let photoOutput = self.photoOutput else { return }
let settings = AVCapturePhotoSettings()
photoOutput.capturePhoto(with: settings, delegate: self)
}
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let error = error {
print(error)
return
}
}
...
}
做得好的例子:
final class CameraViewController: UIViewController {
...
@IBAction func captureButtonDidTap(_ sender: UIButton) {
guard isSessionRunning else { return }
guard let photoOutput = self.photoOutput else { return }
let settings = AVCapturePhotoSettings()
let processor = CameraCaptureProcessor(photoOutput: photoOutput, settings: settings)
self.capturedDelegate = processor
processor.capturePhoto()
}
...
}
final class CameraCaptureProcessor: NSObject, AVCapturePhotoCaptureDelegate {
private var photoOutput: AVCapturePhotoOutput!
private(set) var settings: AVCapturePhotoSettings!
convenience init(photoOutput: AVCapturePhotoOutput, settings: AVCapturePhotoSettings) {
self.init()
self.photoOutput = photoOutput
self.settings = settings
}
func capturePhoto() {
photoOutput.capturePhoto(with: settings, delegate: self)
}
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
if let error = error {
print(error)
return
}
}
}
虽然这篇文章发表已经快一年了,但在我经历了完全相同的事情之后,我现在才发现它。在我发现这个解释之前,它让我困惑了几个小时
我遵循的是一个可以找到的老例子
对我来说,问题是由于Swift模块。在本例中,通过以下方式引入了自定义错误
class CameraController: NSObject, AVCapturePhotoCaptureDelegate {
enum Error: Swift.Error {
case noDeviceAvailable
case captureSessionMissing
}
...
在CameraController
class CameraController: NSObject, AVCapturePhotoCaptureDelegate {
...
//MARK: - AVCapturePhotoCaptureDelegate
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { ... }
...
由于委托方法中的Error
类型与作用域中可用的CameraController.Error
类型不匹配,因此实际上是导致编译器触发警告
解决方案是将自定义错误
定义移到类的范围之外,或者显式地告诉编译器委托方法使用了Swift.Error
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Swift.Error?) { ... }
谢谢你发布这个!它真的帮助了我!