Swift cameraOverlayView中的自定义快门按钮未执行

Swift cameraOverlayView中的自定义快门按钮未执行,swift,uiimagepickercontroller,cameraoverlayview,Swift,Uiimagepickercontroller,Cameraoverlayview,我正在用Swift做一个定制相机。我这样宣布它是全球性的: let image = UIImagePickerController() @IBAction func shutterTapped(_ sender: Any) { print("shutterTapped") image.takePicture() } 我在IB中制作了OverlayVC(UIViewController)。制作了一个快门按钮,并将其连接如下: let image = UIImagePickerC

我正在用Swift做一个定制相机。我这样宣布它是全球性的:

let image = UIImagePickerController()
@IBAction func shutterTapped(_ sender: Any) {
    print("shutterTapped")
    image.takePicture()
}
我在IB中制作了
OverlayVC(UIViewController)
。制作了一个快门按钮,并将其连接如下:

let image = UIImagePickerController()
@IBAction func shutterTapped(_ sender: Any) {
    print("shutterTapped")
    image.takePicture()
}
在演示之前,我将实例化此覆盖:

image.delegate = self
image.sourceType = .camera
image.cameraDevice = .front
image.allowsEditing = false
let overlay = self.storyboard?.instantiateViewController(withIdentifier: "OverlayVC")
image.cameraOverlayView = overlay?.view
image.showsCameraControls = false
self.present(image, animated: true, completion: nil)

现在,当我运行内置设备并点击快门按钮时,我可以直观地看到它正在被点击(淡出/进入),但是
shutterTapped()
中的代码从未执行。

为什么它没有真正工作?

添加视图控制器的视图将删除控制器本身,并且没有人能够实际获取事件。因此,您可以看到视图,但不能看到事件。为了支持这一点:

实际适用于您的代码的解决方案是:

image.cameraOverlayView = overlay?.view
if let viewController  = overlay {

    for view in viewController.view.subviews {
        if let button = view as? UIButton {
           button.addTarget(self, action: #selector(self.takePicture), for: UIControlEvents.touchDown)
        }
    }
}
您还可以向其添加标记,以便在按钮较多时检查哪个按钮是哪个按钮

替代解决方案:

image.cameraOverlayView = overlay?.view
if let viewController  = overlay {

    for view in viewController.view.subviews {
        if let button = view as? UIButton {
           button.addTarget(self, action: #selector(self.takePicture), for: UIControlEvents.touchDown)
        }
    }
}
为它创建
UIView
子类和xib。与您在
OverlayVC
中的视图相同。然后,在添加覆盖时,请使用以下命令:

image.sourceType = .camera
image.cameraDevice = .front
image.allowsEditing = false
let myOverlay = Bundle.main.loadNibNamed("CameraOverlay", owner: self, options: nil)
image.cameraOverlayView = myOverlay?.first as! UIView
image.showsCameraControls = false
self.present(image, animated: true, completion: nil)

请注意,在向
UIView

施放时,强制展开应该使用
guard
if let
进行保护。最简单的问题:您是否尝试重新连接IBAction?@Miknash刚刚尝试过,但没有帮助。我认为您的操作需要与控制器“OverlayVC”连接然后通过您呼叫的代理通知控制器拍照。只需将iAction与OverlayVC连接起来,并检查是否调用了该函数。如果可以,我将写下将事件传播到调用视图所需的代码controller@Miknash但我甚至无法从这个IBAction打印日志,更不用说向其他VC发布通知了。Shutter是在OverlayVC中点击的还是在调用UIImagePickerController的视图控制器中点击的?太好了,很高兴提供帮助。别忘了分配赏金