【iOS13】UIImagePickerControllerでisModalInPresentationがtrueでもSwipe Down Closeできることに対する対処法


TL;DR

  • UIImagePickerControllerをChild ViewControllerとしてもったViewControllerを定義
    • イニシャライザの中でUIViewController.isModalInPresentationtrueにする

iOS13から入ったisModalInPresentationでSwipe Down Closeを防げる

UIViewControllermodalPresentationStyle.pageSheetにセットされると、そのビューをSwipe Downで閉じることが可能です。1

閉じられることの防止策の一つの手として、iOS13から入ったUIViewController.isModalInPresentationtrueにするという手があります。

let vc = UIViewController() 
// iOS13だとpresent時に、デフォルトで`vc.modalPresentationStyle` が `.pageSheet` のときと同様の動作になる
// Swipe Down Closeを防ぐために、isModalInPresentationをtrueにする
vc.isModalInPresentation = true
present(vc, animated: true, completion: nil)

UIImagePickerControllerだとisModalInPresentationtrueにしてもSwipe Down Closeを防げない

表題にもある通り、UIImagePickerControllerisModalInPresentationtrueにしてもSwipe Down Closeを防げません。

let vc = UIImagePickerController() 
// isModalInPresentationをtrueにしてもSwipe Down Closeできてしまいます
vc.isModalInPresentation = true
present(vc, animated: true, completion: nil)

対処方法

まず、UIImagePickerControllerをChild ViewControllerとしてもったViewControllerを定義します。
このとき、イニシャライザの中でUIViewController.isModalInPresentationtrueにしましょう。


@available(iOS 13.0, *) // `isModalInPresentation` がiOS13からなので
class ImagePickerControllerContainer: UIViewController {

   // あえてイニシャライザでimagePickerを受け取るようにしたほうがDelegateの設定とかやりやすい
   init(imagePicker: UIImagePickerController) {
      super.init(nibName: nil, bundle: nil)

      isModalInPresentation = true

      addChild(imagePicker)
      imagePicker.didMove(toParent: self)
      view.addSubview(imagePicker.view)
   }

   ...

このクラスはSwipe Down CloseできないImage Pickerとして利用することができます。

let picker = UIImagePickerController() 
let vc = ImagePickerControllerContainer(imagePicker: picker) 
present(vc, animated: true, completion: nil)

諸注意

かなりアドホックなクラスなので、プライベートクラスで定義して必用なときだけ使うほうが無難です。

// どっかのクラスのNested Typeとして定義したり
private class ImagePickerControllerContainer: UIViewController {
   ...

参考文献


  1. iOS13だとdefaultで.pageSheetと同様の状態になります。というのも、iOS13だとmodalPresentationStyleは、.automaticがDefault Valueであり、直接.pageSheetが指定されているわけではないです。https://developer.apple.com/documentation/uikit/uiviewcontroller/1621355-modalpresentationstyle