文字っぽいの。

文字を書いています。写真も混ざります。

iPadではpopover、iPhoneではsheetとして表示されるModalをUIKitで実装する。

課題

iPadではpopoverとして表示をしたいが、iPhoneでは画面が狭いのでsheetとして表示したいということがある。 またsheetとして表示するならば、 UISheetPresentationController を利用して、いわゆるハーフモーダルにも対応した実装を行いたい。

実装

final class ViewController: UIViewController {
    @IBAction func settingButtonTouchUpInside(_ sender: UIButton) {
        let viewController = PopoverViewController.viewController()

        viewController.modalPresentationStyle = .popover
        viewController.popoverPresentationController?.delegate = self
        viewController.popoverPresentationController?.sourceView = sender
        viewController.popoverPresentationController?.sourceRect = sender.bounds
        viewController.popoverPresentationController?.permittedArrowDirections = .up

        // NOTE: ここで次の設定をしても sheetPresentationController が nil のため反映されない
        // viewController.sheetPresentationController?.detents = [.medium(), .large()]
        // viewController.sheetPresentationController?.prefersGrabberVisible = true

        present(viewController, animated: true)
    }

}

extension ViewController: UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        return traitCollection.horizontalSizeClass == .compact ? .formSheet : .none
    }

    func presentationController(_ presentationController: UIPresentationController, prepare adaptivePresentationController: UIPresentationController) {
        if let sheet = adaptivePresentationController as? UISheetPresentationController {
            sheet.detents = [.medium(), .large()]
            sheet.prefersGrabberVisible = true
        }
    }
}

結果