3
0

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 3 years have passed since last update.

【UIKit】ハーフモーダルのやり方

Posted at

はじめに

いつかやってみたかったハーフモーダルの実装、
ドキュメントや記事を見る限り、思ったより簡単?そうに思えたのでやってみました。

整理

モーダルの表示

表示: 親画面.present(子画面:animated:completion:)
遷移スタイル: UIModalTransitionStyle.coverVertical※デフォルト
表示スタイル: UIModalPresentationStyle.automatic※デフォルト
👉  子画面.modalPresentationStyle = .popoverに変更する

モーダルの設定

UISheetPresentationControllerを取得、detentsを変更する

ポップオーバー:子画面.popoverPresentationController
シート:ポップオーバー.adaptiveSheetPresentationController

ディテント(戻り止め): UISheetPresentationController.detents = [.large()]※デフォルト
👉 シート.detents = [.medium(), .large()]に変更してハーフモーダル可にする
👉 シート.detents = [.medium()]ハーフモーダルのみの場合

条件により詳細設定

■ ハーフモーダル表示中に子画面自体をスクロールさせる(フルモーダル化はエッジ引き上げ)
👉シート.prefersScrollingExpandsWhenScrolledToEdge = falseにする

■ 特定のイベント後にハーフモーダルにする場合👉

シート.animateChanges {
    シート.selectedDetentIdentifier = .medium
}

■ ハーフモーダル表示中に親画面も操作可能にさせる
👉シート.largestUndimmedDetentIdentifier = .mediumにする

■ (デバイス横向き時など)モダールが画面いっぱいに表示され困る場合
👉シート.prefersEdgeAttachedInCompactHeight = trueにする
※デフォルトはfalse

さらに横幅を指定したい場合は、
シート.widthFollowsPreferredContentSizeWhenEdgeAttached = true
※デフォルトはfalse
にすることで子画面.preferredContentSizeの値でカスタマイズできる

■ 他にもモーダルの角を丸くしたり、上部につまみを付けたりできる
角の丸み: シート.preferredCornerRadius = 20.0 ※デフォルトはnil
つまみ: シート.prefersGrabberVisible = true ※デフォルトはfalse

モーダルのクローズ

クローズ: dismiss(animated:completion:)

実装

親画面でモーダル表示の設定を行う

MainViewController
    func showHalfModal() {
        let storyboard = UIStoryboard(name: "HalfModal", bundle: nil)
        let vc = storyboard.instantiateViewController(identifier: "HalfModal")
        guard let modalVC = vc as? HalfModalViewController else { return }
        modalVC.delegate = self

        // スタイルをポップオーバーに設定
        modalVC.modalPresentationStyle = .popover
        if let popover = modalVC.popoverPresentationController {
            // iOS 15.0から設定可能なので
            if #available(iOS 15.0, *) {
                let sheet = popover.adaptiveSheetPresentationController
                // ハーフモーダルのみに設定
                sheet.detents = [.medium()]

                // 以下オプションの設定
                sheet.prefersScrollingExpandsWhenScrolledToEdge = false
                sheet.prefersEdgeAttachedInCompactHeight = true
                sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
            }
        }
        // モーダル表示
        self.present(modalVC, animated: true)
    }

公式ドキュメント書き方はこんな感じでviewControllerから直接sheetを取ってた

func showMyViewControllerInACustomizedSheet() {
    let viewControllerToPresent = MyViewController()
    if let sheet = viewControllerToPresent.sheetPresentationController {
        sheet.detents = [.medium(), .large()]
        sheet.largestUndimmedDetentIdentifier = .medium
        sheet.prefersScrollingExpandsWhenScrolledToEdge = false
        sheet.prefersEdgeAttachedInCompactHeight = true
        sheet.widthFollowsPreferredContentSizeWhenEdgeAttached = true
    }
    present(viewControllerToPresent, animated: true, completion: nil)
}

感想

実装が簡単で感動しました。
実際に個人開発中のアプリでハーフモーダルを実装していじってみましたが、操作性がアップした気がします。
今後は可能な限りハーフモーダル(もしくはハーフ&フル)に切り替えていこうと思います。

参考記事

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?