Popoverの2つの実装方法を比較する

  • 26
    いいね
  • 0
    コメント

はじめに

Popoverの実装方法に関して、従来使っていたUIPopoverControllerクラスがiOS9で廃止予定とされました。
(今さらですが、コード書き換えの際の備忘のために、)新旧でどう違うのかをメモしたいと思います。

違い

古い方法 新しい方法
発想 中身のViewControllerを入れたUIPopoverControllerに表示させる 中身のVCのpopoverPresentationControllerに条件をセットして、表示元のVCに表示させる
iOS 3.2〜9.0 (9.0でDeprecatedになりました。) 8.0〜
iPhone 不可 (adaptivePresentationStyleの指定でポップオーバーとモーダルの表示を切り替えられる。)
インスタンス管理 UIPopoverControllerのインスタンスを強参照で保持。不要になった時点でnilをセットして解放。 特に意識しないで済む。(VCのサイクルに従う。)

特に、iPhoneでPopoverを扱える点は大きな差です。
また、インスタンス管理がシンプルになるのも魅力的です。

古い方法のコード例

基本的にこのような構造になります。
ContentViewControllerが中身のviewControllerです。

ViewController.swift
class ViewController: UIViewController, UIPopoverControllerDelegate {
    var popover: UIPopoverController?

    @IBAction func tapUIPopoverController(_ sender: UIButton) {

        //Only for iPad
        if UIDevice.current.userInterfaceIdiom != .pad {
            print("UIPopoverController is only for iPad.")
            return
        }

        //Prepare the instance of ContentViewController which is the content of popover.
        let contentVC = ContentViewController()
        //set size
        contentVC.preferredContentSize = CGSize(width: 300, height: 300)
        //make popover controller
        popover = UIPopoverController(contentViewController: contentVC)
        //set delegate
        popover?.delegate = self
        //present
        popover?.present(from: sender.frame, in: view, permittedArrowDirections: .any, animated: true)
    }

    //UIPopoverControllerDelegate for UIPopoverController
    func popoverControllerDidDismissPopover(_ popoverController: UIPopoverController) {
        //release
        popover = nil
    }

}

新しい方法の例

ViewController.swift
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {

    @IBAction func tapModalPresentationStyle(_ sender: UIButton) {
        //Prepare the instance of ContentViewController which is the content of popover.
        let contentVC = ContentViewController()
        //define use of popover
        contentVC.modalPresentationStyle = .popover
        //set size
        contentVC.preferredContentSize = CGSize(width: 300, height: 300)
        //set origin
        contentVC.popoverPresentationController?.sourceView = view
        contentVC.popoverPresentationController?.sourceRect = sender.frame
        //set arrow direction
        contentVC.popoverPresentationController?.permittedArrowDirections = .any
        //set delegate
        contentVC.popoverPresentationController?.delegate = self
        //present
        present(contentVC, animated: true, completion: nil)
    }

    /// Popover appears on iPhone
    func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        return .none
    }

}

新旧の比較デモ

上のコードが動くデモプロジェクトを作りました。
HowToDisplayPopover
https://github.com/hsylife/HowToDisplayPopover

感想

・そもそも、Popoverはあまり使われていない印象がありますが、個人的にはとても興味深いUIだと考えています。
・UXの面を考えた場合、画面遷移せずに何かを見ながら入力操作できる点や、指の移動が小さくて済む点で、モーダルやアクションシートよりも有利となることがある。
・開発の面からは、iPhone/iPadに共通のUIを持たせることができるので、デザイン、実装の手続きを一本化できる点が魅力。

関連リンク

UIPopoverPresentationController
UIPopoverController