【问题标题】:delegate method doesn't get called for UIimagePickerController没有为 UIimagePickerController 调用委托方法
【发布时间】:2019-02-19 08:53:38
【问题描述】:

我正在尝试创建协议,我可以根据用户的选择使用相机或媒体库打开 UIimagePickerController。

这里有一些代码:

import UIKit
protocol PFImagePickerProtocol: UIImagePickerControllerDelegate,UINavigationControllerDelegate where Self: UIViewController {
    func didSelectImage(image: UIImage?, error: Bool)
    func didCancelledImageSelection()
}
extension PFImagePickerProtocol {
    func openImageSelector(withCorp cropEnabled:Bool)  {
        let alertController = UIAlertController(title: "Action Sheet", message: "What would you like to do?", preferredStyle: .actionSheet)

        let camera = UIAlertAction(title: "Camera", style: .default) { (action) in
            self.openImagePicker(withCorp: cropEnabled, sourceType: .camera)
        }
        let library = UIAlertAction(title: "Photo Library", style: .default) { (action) in
            self.openImagePicker(withCorp: cropEnabled, sourceType: .photoLibrary)
        }
        alertController.addAction(camera)
        alertController.addAction(library)

        self.present(alertController, animated: true, completion: nil)
    }

    private func openImagePicker(withCorp cropEnabled:Bool, sourceType: UIImagePickerController.SourceType)  {
        let pickerVc = UIImagePickerController()
        pickerVc.allowsEditing = cropEnabled
        pickerVc.sourceType = sourceType
        pickerVc.delegate = self //is this the problem?
        self.present(pickerVc, animated: true, completion: nil)
    }
}

extension PFImagePickerProtocol{
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        self.dismiss(animated: true, completion: nil)
        didCancelledImageSelection()
    }
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            didSelectImage(image: image, error: false)
            return
        } else {
            didSelectImage(image: nil, error: true)
        }
        self.dismiss(animated: true, completion: nil)
    }
}

当我运行代码时。未调用函数“didFinishPickingMediaWithInfo”。

我发现this 的答案很有用。但如果有什么可以解决这个问题的。请在这里分享。

随意评论代码。

【问题讨论】:

    标签: swift4 uiimagepickercontroller swift-protocols protocol-oriented


    【解决方案1】:

    请编写如下代码:

    protocol PFImagePickerProtocol {
        func didSelectImage(image: UIImage?, error: Bool)
        func didCancelledImageSelection()
    }
    

    并编写如下包含委托方法的扩展:

    extension YourViewController {
        func openImageSelector(withCorp cropEnabled:Bool)  {
            let alertController = UIAlertController(title: "Action Sheet", message: "What would you like to do?", preferredStyle: .actionSheet)
    
            let camera = UIAlertAction(title: "Camera", style: .default) { (action) in
                self.openImagePicker(withCorp: cropEnabled, sourceType: .camera)
            }
            let library = UIAlertAction(title: "Photo Library", style: .default) { (action) in
                self.openImagePicker(withCorp: cropEnabled, sourceType: .photoLibrary)
            }
            alertController.addAction(camera)
            alertController.addAction(library)
    
            self.present(alertController, animated: true, completion: nil)
        }
    
        private func openImagePicker(withCorp cropEnabled:Bool, sourceType: UIImagePickerController.SourceType)  {
            let pickerVc = UIImagePickerController()
            pickerVc.allowsEditing = cropEnabled
            pickerVc.sourceType = sourceType
            pickerVc.delegate = self //This will set your picker delegate to view controller class & the below extension conforms the delegates.
            self.present(pickerVc, animated: true, completion: nil)
        }
    }
    
    extension YourViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            self.dismiss(animated: true, completion: nil)
            didCancelledImageSelection()
        }
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
                didSelectImage(image: image, error: false)
                return
            } else {
                didSelectImage(image: nil, error: true)
            }
            self.dismiss(animated: true, completion: nil)
        }
    }
    

    我认为您可以将上述所有代码编写在一个视图控制器中,例如 AbstractViewController,它是 UIViewController 的一个子类,并且您所有其他具有此功能的视图控制器都有其超类作为 AbstractViewController。

    class AbstractViewController: UIViewController {
        // Do above code here
    }
    
    class OtherViewController: AbstractViewController {
        // Classes that needs to implement the image picker functionality
    }
    

    【讨论】:

    • 我们在为协议编写扩展时不能有继承子句。
    • 不,我们不能在编写协议时继承,我们只能在编写 UIViewControllers 或其扩展时继承。
    • 也只继承给定扩展可能确认的那些委托或数据源。
    • 是的。我确实尝试过这段代码。给出错误“协议'PFImagePickerProtocol'的扩展不能有继承子句”
    • 那你为什么要扩展协议,只是扩展视图控制器以在扩展中实现委托和数据源。
    【解决方案2】:

    PFImagePickerManager 类

     typealias PFImagePickerTarget = UIImagePickerControllerDelegate & UINavigationControllerDelegate 
        class PFImagePickerManager {
            static var shared: PFImagePickerManager = PFImagePickerManager()
            var target: PFImagePickerTarget!
            private init() {}
    
             func openImageSelector(target: PFImagePickerTarget, shouldCrop: Bool) {
                self.target = target
                let alertController = UIAlertController(title: PFConstants.PFImagePicker.actionSheetTitle, message: kEmptyStr, preferredStyle: .actionSheet)
                let camera = UIAlertAction(title: PFConstants.PFImagePicker.camera, style: .default) { (action) in
                    self.openImagePicker(withCorp: shouldCrop, sourceType: .camera)
                }
                let library = UIAlertAction(title: PFConstants.PFImagePicker.photoLibrary, style: .default) { (action) in
                    self.openImagePicker(withCorp: shouldCrop, sourceType: .photoLibrary)
                }
                let cancel = UIAlertAction(title: PFConstants.PFImagePicker.cancel, style: .cancel) { (action) in
    
                }
                alertController.addAction(camera)
                alertController.addAction(library)
                alertController.addAction(cancel)
                if let vc = target as? PFBaseViewController {
                    vc.present(alertController, animated: true, completion: nil)
                }
            }
    
            private func openImagePicker(withCorp cropEnabled:Bool, sourceType: UIImagePickerController.SourceType)  {
    
                let pickerVc = UIImagePickerController()
                pickerVc.allowsEditing = cropEnabled
                pickerVc.sourceType = sourceType
                pickerVc.delegate = target
                if sourceType == .photoLibrary {
                    pickerVc.navigationBar.tintColor = UIColor.appThemePrimaryColor()
                }
                if let vc = target as? PFBaseViewController {
                    vc.present(pickerVc, animated: true, completion: nil)
                }
    
            }
    
        }
    

    你需要扩展PFImagePickerTarget

    extension YourViewController: PFImagePickerTarget {
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            picker.dismiss(animated: true, completion: nil)
        }
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
            if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
                PFViewUtility.dispatchOnMainThread {
                    self.VMCreateGR.changeDatafor(.image, data: image)
                    self.tblInputs.reloadData()
                }
            } else {
                self.view.makeToast("Error while selecting image. Please try again.")
            }
            picker.dismiss(animated: true, completion: nil)
        }
    }
    

    并在 ViewController 中启动图像选择器

        class AnyViewController: UIViewController {
            // In some method like viewDidLoad call the below line
            PFImagePickerManager.shared.openImageSelector(target: self, shouldCrop: true)
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 2020-11-14
      • 2020-11-28
      相关资源
      最近更新 更多