【Swift4】ポップアップを表示する方法まとめ

ポップアップを出そうとした際に、関連ワードや方法が複数あって混乱したので、調べたことをまとめてみました。
これからポップアップを実装する方のお役に立てば幸いです。

# UIModalPresentationStyle
## 概要
[UIModalPresentationStyle - UIKit | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uimodalpresentationstyle)

モーダル表示の際の「表示スタイル」を指定できます。
ViewControllerの中に列挙型として宣言されており、色々な種類があります。

* `.fullScreen`（フルスクリーンで表示 / ステータスバーに重なる。）
* `.pageSheet`（幅768×高さフルで表示 / ステータスバーに重ならない）
* `.formSheet`（幅540×高さ620で画面中央に表示 / ステータスバーに重ならない）
* `.popover`（**後述の`UIPopoverPresentationController`と一緒に使われる**）
* `.custom`（**後述の`UIPresentationController`と一緒に使われる**）
etc...


```swift
public enum UIModalPresentationStyle : Int {

    
    case fullScreen

    @available(iOS 3.2, *)
    case pageSheet

    @available(iOS 3.2, *)
    case formSheet

    @available(iOS 3.2, *)
    case currentContext

    @available(iOS 7.0, *)
    case custom

    @available(iOS 8.0, *)
    case overFullScreen

    @available(iOS 8.0, *)
    case overCurrentContext

    @available(iOS 8.0, *)
    case popover

    
    @available(iOS 7.0, *)
    case none
}
```

## 使い方
ViewControllerを2つ用意します。
<img width="635" alt="スクリーンショット 2019-01-19 18.21.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/112818/2f8a7587-344e-e878-f79a-7162f42d0ccb.png">


presentメソッドを使ったいつもの画面遷移に、好きな`modalPresentationStyle`を指定するだけで簡単にポップアップを表示できます。（個人的には一番お手軽にポップアップを表示させられる方法だと思います。）

```Swift
@IBAction func btnTapped(_ sender: Any) {
    let storyboard: UIStoryboard = self.storyboard!
    let second = storyboard.instantiateViewController(withIdentifier: "second")
    // modalPresentationStyleを指定する
    second.modalPresentationStyle = .pageSheet
    self.present(second, animated: true, completion: nil)
}
```

**▼.pageSheet（iPad Pro (9.7-inch)）**
<img width="500" alt="Simulator Screen Shot - iPad Pro (9.7-inch) - 2019-01-19 at 16.26.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/112818/7d7c9155-8b23-381f-dc65-ba66c1256495.png">

**▼.formSheet（iPad Pro (9.7-inch)）**
<img width="500" alt="Simulator Screen Shot - iPad Pro (9.7-inch) - 2019-01-19 at 16.19.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/112818/47ad39bf-d23c-16f3-5205-0167058256d6.png">

## 使ってみた感想
実装が簡単で、背景を勝手に暗くしてくれるのはメリットですが、
`.pageSheet`や`.formSheet`はiPadでしかポップアップにならなかったり（iPhoneではフルスクリーンのモーダル表示となります）、上に乗せる画面サイズが基本固定だったりと、若干の使いづらさはあるかなーと思います。

# UIPopoverPresentationController
## 概要
[UIPopoverPresentationController - UIKit | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller)

`UIModalPresentationStyle.popover`がセットされたViewControllerの画面構成やふるまいを制御するために使われるクラスです。
画面中央に窓を表示するのではなく、ある要素からピヨッと吹き出し風にポップアップを出したいときに使えます。
iOS3.2から使われていた`UIPopoverController`がiOS9で非推奨となり、代わりに登場したのがこの`UIPopoverPresentationController`。それによって、iPhoneでもようやく合法的にポップアップが出せるようになりました。

## 使い方
別記事にまとめてますので、こちらをご覧ください↓
[【Swift4】UIPopoverPresentationControllerを使ってiPhone/iPad両対応のPopoverを出してみた - Qiita](https://qiita.com/orimomo/items/1a44337de974a72b6266)

## 使ってみた感想
画面サイズや矢印を出す方向を自由に決めることができますし、ポップアップが立体的に見えるようにグラデーションの影をつけてくれるのもGoodです。吹き出し風ポップアップを作りたいなら使わない手はないと思います。

# UIPresentationController
## 概要
[UIPresentationController - UIKit | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uipresentationcontroller)
` UIModalPresentationStyle.custom`がセットされたViewControllerのふるまいを制御するために使われるクラスで、ポップアップ表示の詳細なカスタムがしたいときに使います。
画面遷移の状態をトラッキングできるメソッドも用意されています。

* `func presentationTransitionWillBegin()`
* `func presentationTransitionDidEnd(Bool)`
* `dismissalTransitionWillBegin()`
* `func dismissalTransitionDidEnd(Bool)`

## 使い方
わかりやすい記事がありますのでご参照ください↓
[【Swift】UIPresentationControllerを使ってモーダルビューを表示する - Qiita](https://qiita.com/wai21/items/9b40192eb3ee07375016)

## 使ってみた感想
背景の色や透過率、上に乗せるビューのサイズなどを遷移状態によって変えられるのは、ポップアップを自由にカスタムしたい場合にとても役立つと感じました。一方で背景を暗くしたりするのも自分で実装しなくてはいけないので、そこまで自由度高くなくていいよという場合はわざわざ使う必要はないのかなと思います。

# その他
## UIAlertController
[【Swift】アラートを表示する（Alert／ActionSheet）  - Qiita](https://qiita.com/funafuna/items/b76e62eb82fc8d788da5)
アラートを出すために使われるので若干毛色が異なりますが、一応載せておきます。

## ライブラリ
ライブラリを使うという方法もあります。たとえばMJPopupViewControllerなど。
[GitHub - martinjuhasz/MJPopupViewController](https://github.com/martinjuhasz/MJPopupViewController)
アニメーションのレパートリーが多く、上下左右どこからでもポップアップを表示できます。
若干グラデーションのかかった暗い背景を出してくれたり、上に乗せるビューにも立体的な影を付けてくれたりするので、リッチなポップアップを使いたい場合は選択肢に入れてもいいかもしれません。
（ライブラリはObjective-Cで書かれていますが、もちろんSwiftでも使えます。）

## 自作する
どうしてもしっくりくるものが無い！という方は、少し骨が折れますが、自作するのも一つの手かと思います。作り方は下記記事に譲ります。
[【swift4】自作でポップアップを作成してみた。 | 物置エンジニアの備忘録](https://logist3.com/swift-popup/)
[Swiftストーリーボードでポップアップビューを実装 - Qiita](https://qiita.com/dondoko-susumu/items/7b48413f63a771484fbe)