【发布时间】:2019-01-22 16:15:03
【问题描述】:
我正在开发使用照片输出来捕捉照片的自定义相机。
当用户点击捕获按钮时,photoOutput.capturePhoto(with: settings, delegate: self)被调用,它的第二个参数为self代表UIViewController,因为UIViewController符合AVCapturePhotoCaptureDelegate。
但是,使用消息实现func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) 时会出现 1 个奇怪的警告 -
实例方法 'photoOutput(:didFinishProcessingPhoto:error:)' 几乎匹配协议 'AVCapturePhotoCaptureDelegate' 的可选要求 'photoOutput(:didFinishProcessingPhoto:error:)'
此外,当点击带有错误消息的捕获按钮时会发生崩溃 -
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[AVCapturePhotoOutput capturePhotoWithSettings:delegate:] 如果您在设置中指定非零格式字典,则您的代理必须响应选择器 captureOutput:didFinishProcessingPhoto :错误:
即使设置的格式字典不是 nil。
但是当我实现一个符合 AVCapturePhotoCaptureDelegate 的自定义类时,没有任何警告,并且运行良好。
所以我很好奇.. 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 uiviewcontroller camera