1. hsylife

    Posted

    hsylife
Changes in title
+Popoverの2つの実装方法を比較する
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,95 @@
+##はじめに
+Popoverの実装方法に関して、従来使っていたUIPopoverControllerクラスがiOS9で廃止予定とされました。
+(今さらですが、コード書き換えの際の備忘のために、)新旧でどう違うのかをメモしたいと思います。
+
+##異同
+| | 古い方法 | 新しい方法 |
+|:-:|:-:|:-:|
+|発想 |中身のViewControllerを入れたUIPopoverControllerに表示させる| 中身のVCのPresentationControllerに条件をセットして、表示元のVCに表示させる |
+|iOS|3.2〜9.0 (9.0でDeprecatedになりました。)|8.0〜|
+|iPhone|不可|**可** (adaptivePresentationStyleの指定でポップオーバーとモーダルの表示を切り替えられる。)|
+|インスタンス管理|UIPopoverControllerのインスタンスを強参照で保持。不要になった時点でnilをセットして解放。|特に意識しないで済む。(VCのサイクルに従う。) |
+
+特に、iPhoneでPopoverを扱える点は大きな差です。
+また、インスタンス管理がシンプルになるのも魅力的です。
+
+##古い方法のコード例
+基本的にこのような構造になります。
+ContentViewControllerが中身のviewControllerです。
+
+```swift: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
+ }
+
+}
+```
+
+##新しい方法の例
+```swift: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](https://developer.apple.com/reference/uikit/uipopoverpresentationcontroller)
+[UIPopoverController](https://developer.apple.com/reference/uikit/uipopovercontroller)