6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

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

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?