48
47

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

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

Last updated at Posted at 2016-10-11

##はじめに
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

48
47
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
48
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?