【问题标题】:UIImagePickerControllerDelegate didFinishPickingMediaWithInfo not calledUIImagePickerControllerDelegate didFinishPickingMediaWithInfo 未调用
【发布时间】:2018-09-01 16:12:48
【问题描述】:

我有一个项目,其中有许多使用 imagePicker 的视图控制器。每次,我都必须再次复制 didFinishPickingMediaWithInfo 并且只更改一些代码。

然后我决定把 UIImagePickerControllerDelegate 和 UINavigationControllerDelegate 包装成我自己的协议,并扩展这个协议来实现 didFinishPickingMediaWithInfo。但是,根本没有调用 didFinishPickingMediaWithInfo。其他部分运行良好,图像拾取器和相机视图显示良好,但拾取完成后,没有调用 didFinish 函数。

我在网上看到了一些建议,比如这个。他们使用具体类来扭曲这两个协议,而不是接口。

https://gist.github.com/rpassis/4622291029cd12e4ce2b7585d3e62d15

我不知道为什么我的解决方案是错误的,谁能告诉我我的代码错误的原因。也许我误解了协议和协议扩展的某些部分。顺便说一句,我发现一个警告是

非'@objc' 方法 'imagePickerController(_:didFinishPickingMediaWithInfo:)' 没有 满足“@objc”协议的可选要求 'UIImagePickerControllerDelegate'

另一种解释来自 Swift protocol implementing another @objc protocol

我的代码如下所示。

public protocol ImagePickerDelegate: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func successActionFromCamera(with localIdentifier: String, picker: UIImagePickerController)
    func successActionFromPhotoLibrary(with imageURL: URL, picker: UIImagePickerController)
}

我的自定义委托的扩展

extension ImagePickerDelegate {

public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    //camera
    if info[UIImagePickerControllerReferenceURL] == nil {

        func savePhotoAndTakeAction() {
            var imagePlaceholder:PHObjectPlaceholder!

            DispatchQueue.global(qos: .default).async {
                PHPhotoLibrary.shared().performChanges({
                    let request = PHAssetChangeRequest.creationRequestForAsset(from: info[UIImagePickerControllerOriginalImage]! as! UIImage)
                    imagePlaceholder = request.placeholderForCreatedAsset!
                }, completionHandler: { (success, error) -> Void in
                    DispatchQueue.main.async {
                        if success {
                            //image saved to photos library.
                            self.successActionFromCamera(with: imagePlaceholder.localIdentifier, picker: picker)
                        } else {
                            picker.dismiss(animated: true, completion: nil)
                            print(error!.localizedDescription)
                        }
                        picker.dismiss(animated: true, completion: nil)
                    }
                })
            }
        }

        switch PHPhotoLibrary.authorizationStatus() {
        case .denied:
            picker.dismiss(animated: false) { BasePhotoUtil.showAccessAlertController(false) }
            return
        case .notDetermined:
            PHPhotoLibrary.requestAuthorization({ (newStatus) in
                if (newStatus == .authorized) {
                    savePhotoAndTakeAction()
                }
                else {
                    DispatchQueue.main.async {
                        picker.dismiss(animated: false, completion: { BasePhotoUtil.showAccessAlertController(false) })
                    }
                    return
                }
            })
        default:
            break
        }
        savePhotoAndTakeAction()
    } else {
        //photo library
        if let imageURL = info[UIImagePickerControllerReferenceURL] as? URL {
            self.successActionFromPhotoLibrary(with: imageURL, picker: picker)
        } else {
            picker.dismiss(animated: true, completion: nil)
        }
    }
}

ImagePicker 呈现函数

private static func showImagePickerView(isCamera: Bool, currentVC: UIViewController) {

    let imagePicker = UIImagePickerController()
    imagePicker.delegate = currentVC as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
    imagePicker.allowsEditing = false
    imagePicker.navigationBar.isTranslucent = false

    if isCamera {
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            imagePicker.sourceType = .camera
            imagePicker.cameraCaptureMode = .photo
        } else {
            BaseAlertUtil.showNoFunctionAlertController(title: "No Camera", message: "Sorry, this device has no camera")
        }
    } else {
        imagePicker.sourceType = .photoLibrary
    }
    currentVC.present(imagePicker, animated: true) {
        BaseThemeUtil.setStatusBarStyle(.default)
    }
}

【问题讨论】:

  • 你设置了picker.delegate = self吗?
  • 您需要显示创建图像选择器、分配代理和显示图像选择器的代码。
  • 我设置了picker.delegate = self,并创建了图像选择器。选择器可以显示,但是在选择照片后,没有调用didFinish函数

标签: ios objective-c swift protocol-extension


【解决方案1】:

这个问题是重复的。其实不是ImagePicker问题,更像是协议扩展问题。原因是swift协议不能扩展objc协议。

我想我已经在我的问题中给出了解决方案和解释。

解释:

  1. Swift protocol implementing another @objc protocol

  2. Non-'@objc' method does not satisfy optional requirement of '@objc' protocol

解决方案:https://gist.github.com/rpassis/4622291029cd12e4ce2b7585d3e62d15

我将按照上面的解决方案更改我的代码,如果您有任何新想法,请回复我。非常感谢。

【讨论】:

    猜你喜欢
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    相关资源
    最近更新 更多