NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

【UIKit】iOS16から使用できるcustomを使用して任意の高さのモーダルを実装する

概要

iOS16からUIViewControllerで使用できるモーダルがcustomを使用することで任意の高さに設定できるようになりました。 今回は試しにSwiftUIのViewを呼び出して使用してみましたので、その方法について紹介したいと思います。
サンプルやWWDC22での紹介の様子は以下ドキュメント先にあります。
https://developer.apple.com/documentation/uikit/uiviewcontroller/customizing_and_resizing_sheets_in_uikit

実装の様子

またこの記事ではsheet.detentsを使用して表示される画面をモーダルと呼んでいますので、ご認識お願いします。

環境

この記事は以下のバージョン環境のもと作成されたものです。
【Xcode】14.1
【iOS】16.1
【macOS】Monterey 12.6

sheetPresentationControllerの使用方法

iOS15まではUIViewControllerにてsheetPresentationControllerを使用するとモーダルを2段階で表示させる事ができました。

@objc func didTapOpenView(sender _: UIButton) {
    let vc = UIHostingController(rootView: MySwiftUIView())
    if let sheet = vc.sheetPresentationController {
        sheet.detents = [
            .large(),
            .medium(),
        ]
    }
    present(vc, animated: true)
}

SwiftUIのViewについてはUIHostingControllerを使用する事でUIViewControllerでも表示させる事が可能です。 詳細は別記事で紹介していますのでご覧ください。

tech.nri-net.com

sheet.detents内でlarge()もしくはmedium()もしくはその両方を呼び出す事でそれぞれの大きさのモーダルもしくはどちらにも対応した可変可能なモーダルを表示します。

large()及びmedium()の両方使用した時の動作

customで任意の高さのモーダルを表示する

sheet.detents内に以下を追加する事で任意の高さに変更する事ができます。
sheet.detents = [ .custom { context in 0.8 * context.maximumDetentValue } ]
context.maximumDetentValueに対して1を最大としてどれだけの割合の高さを表示させるか指定しています。
例えば0.8とすると8割の高さとなります。
固定で指定したい場合はcustom { context in 300 }とするとできます。 また複数定義することもできます。

@objc func didTapOpenView(sender _: UIButton) {
    let vc = UIHostingController(rootView: MySwiftUIView())
    if let sheet = vc.sheetPresentationController {
        sheet.detents = [
            .large(),
            .medium(),
            .custom { context in
                0.8 * context.maximumDetentValue
            },
            .custom { context in
                0.6 * context.maximumDetentValue
            },
            .custom { context in
                0.4 * context.maximumDetentValue
            },
            .custom { context in
                0.2 * context.maximumDetentValue
            }
        ]
    }
    present(vc, animated: true)
}

これで様々な高さのモーダルを表示することができます。

まとめ

sheet.detentsにてcustomを使用する事で容易に任意の高さに変更できるようになったので非常に使い勝手が良くなりました! これで自前でモーダルの高さを任意にする画面作成から抜け出せます。

執筆者岡優志

iOSエンジニア
iOSを専門とし、モバイルアプリの開発を行なっています。

Twitter