IOS 11 double-click on image rejects UIImagePickerController and presenter presentation controller

We have a photo collector made with UIImagePickerController.

When you double- click (instead of one ) select a photo from the gallery.

  • In iOS 10: UIImagePickerControllerrejected
  • On iOS 11: UIImagePickerControllerrejected, and view manager view also rejected: 0

Is this an iOS 11 bug, or do we need to fix something?


Our code:

  let vc = UIImagePickerController()
  vc.delegate = self
  vc.modalPresentationStyle = .overFullScreen
  vc.allowsEditing = false
  rootVC.present(vc, animated: true) // `rootVC` also presented modally.
+4
source share
1 answer

As a result, we get the solution: install delegate = nilimmediately after calling the delegate to didFinishPickingMediaWithInfo.

public class ImagePicker: NSObject {

   private lazy var viewController = setupActionSheet()
   private var rootViewController: UIViewController?
   private var completionHandler: (([String: Any]) -> Void)?
   private var cancellationHandler: (() -> Void)?
}

extension ImagePicker {

   public func present(on: UIViewController, completionHandler: @escaping (([String: Any]) -> Void)) {
      rootViewController = on
      self.completionHandler = completionHandler
      cancellationHandler = nil
      on.presentAnimated(viewController)
   }

   public func present(on: UIViewController,
                       completionHandler: @escaping (([String: Any]) -> Void),
                       cancellationHandler: @escaping (() -> Void)) {
      rootViewController = on
      self.completionHandler = completionHandler
      self.cancellationHandler = cancellationHandler
      on.presentAnimated(viewController)
   }
}

extension ImagePicker {

   private func setupActionSheet() -> UIAlertController {
      let actionSheet = UIAlertController(actionSheetWithTitle: LocalizedString.Generic.ImagePicker.addPhoto)

      if UIImagePickerController.isSourceTypeAvailable(.camera) {
         actionSheet.addDefaultAction(LocalizedString.Generic.ImagePicker.takePhoto) { [weak self] _ in
            self?.presentImagePicker(.camera)
         }
      }
      actionSheet.addDefaultAction(LocalizedString.Generic.ImagePicker.selectPhoto) { [weak self] _ in
         self?.presentImagePicker(.photoLibrary)
      }
      actionSheet.addCancelAction(LocalizedString.Generic.ButtonTitle.cancel) { [weak self] _ in
         self?.cancellationHandler?()
      }
      return actionSheet
   }

   private func presentImagePicker(_ sourceType: UIImagePickerControllerSourceType) {
      let vc = UIImagePickerController()
      vc.delegate = self
      vc.allowsEditing = false
      vc.sourceType = sourceType
      rootViewController?.present(vc, animated: true)
   }
}

extension ImagePicker: UIImagePickerControllerDelegate {

   public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
      picker.delegate = nil /// It prevents to call delegate when user taps on a few images very fast. seems iOS 11 issue only.
      if picker.sourceType == .camera, let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
         UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
      }
      picker.dismiss(animated: true) {
         self.completionHandler?(info)
      }
   }

   public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
      picker.dismiss(animated: true) {
         self.cancellationHandler?()
      }
   }
}

Using:

  // Somewhere in view controller code.
  imagePicker = ImagePicker()
  imagePicker?.present(on: self) { [weak self] in
     self?.imagePicker = nil
     self?.viewModel.addImage($0)
  }
0
source

Source: https://habr.com/ru/post/1689000/


All Articles