Swift Playgroundsで学ぶiOSプログラミング 第75回
ポップオーバープレゼンテーションコントローラーを使ってメニューを作る
ほかのビューの上に重ねて表示可能なポップオーバーを出現させる
2018年02月12日 18時45分更新
前回は、画面を分割することで、複数のビューコントローラーのビューを同時に表示可能にするスプリットビューコントローラーを取り上げました。このところ、ほかの複数のビューコントローラーの動作を司るような「特殊な」ビューコントローラーを取り上げていましたが、もちろんスプリットビューコントローラーもその一種です。
そして今回も、複数のビューコントローラーの動作や表示を管理するような機能を扱います。それはポップオーバープレゼンテーションコントローラー(UIPopoverPresentationController)と呼ばれるコントローラーによって実現します。文字通どおり、ほかのビューの上に重ねて表示可能なポップオーバーを出現させるためのものです。このコントローラーがこれまでに取り上げてきたものと決定的に違うのは、これはビューコントローラーではないということです。クラスの階層からすると、名前からわかるようにプレゼンテーションコントローラー(UIPresentationController)の一種ということになります。
では、そのプレゼンテーションコントローラーとは何か……。とやっているとなかなか話が進まないので、とりあえずそのあたりは割愛してポップオーバープレゼンテーションコントローラーを実際に使ってみることから始めます。ビューコントローラーではないだけに、使い方はこれまでとだいぶ異なります。クラス階層はともかくとして、コードを見ればすぐに理解できるでしょう。
テーブルビューをポップオーバーとして表示する
今回は、最初からある程度アプリとしての構成を意識したものを作っていくことにしましょう。まずは、プレイグラウンド画面全体に表示するビューコントローラーのクラスDetailViewControllerを定義します。
これは、とりあえず中身が空のビューコントローラーですが、ナビゲーションコントローラーを通して表示することで、ナビゲーションバーを表示しています。それは、ナビゲーション機能を使うためではなく、バーの上にボタンを配置したいからです。ツールバーでもいいのですが、こちらのほうが簡単です。
ナビゲーションバーの上にはバーボタンアイテム(UIBarButtonItem)を配置し、ユーザーがそれをタップすると、同じクラス内のbuttonTappedメソッドが呼ばれるようにしています。
そのメソッドでは、いきなり今回の主役のポップオーバープレゼンテーションコントローラーを使って、ポップオーバーを表示しています。とはいえ、不思議なことに、この中ではそのコントローラーのオブジェクトを作ったりはしていません。空のテーブルビューのオブジェクトを作り、そのオブジェクトの持つpopOverPresentationControllerというプロパティからオブジェクトにアクセスしています。つまり、ポップオーバープレゼンテーションコントローラーのオブジェクトは、最初からすべてのビューコントローラーの中に含まれていることになります。
さらに驚くのは、それを表示する方法です。そのために使うのは、ポップオーバーとして表示する中身(この場合は空のテーブルビュー)でも、ポップオーバープレゼンテーションコントローラーでもありません。最初に定義して画面全体に表示した、とりあえず空のビューコントローラー(self)の持つpresentというメソッドを、引数として空のテーブルビューを指定して呼び出しているのです。
これだけでポップオーバーが表示されるのは、不思議な感じがするでしょう。ポイントは、空のテーブルビューのmodalPresentationStyleに.popoverを指定していることと、その空のテーブルビューから取り出したポップオーバープレゼンテーションコントローラーのオブジェクトのbarButtonItemプロパティに、ナビゲーションバー上に配置したボタンを設定していることです。ポップオーバーは、吹き出し状に表示されるので、必ず「出どころ」を明らかにする必要があります。これでボタンから吹き出すかたちで表示されます。
このプログラムを動かすと、薄いグレーの背景を持った空のビューの上にナビゲーションバーが表示され、そこには「Pop」というボタンが配置されています。
これをタップすると、そのボタンから吹き出しとして空のテーブルビューが表示されます。
ここまでできれば、今回の話はほとんど終わったようなものです。あとは、画面全体に配置したベースのビューと、ポップオーバーとして出現させたビューに何を表示するかということだけです。
この連載の記事
- 第100回 SceneKitの物理現象シミュレーションとアニメーションをARKitに持ち込む
- 第99回 「物理学体」と「物理学場」を設定して物理現象をシミュレーション
- 第98回 SceneKitのノードに動きを加えるプログラム
- 第97回 いろいろな形のノードをシーンの中に配置する
- 第96回 SceneKitの基礎シーンビュー、シーン、ノードを理解する
- 第95回 現実世界の床にボールや自動車のモデルを配置する
- 第94回 ARKitを使って非現実世界との融合に備える
- 第93回 ARKitが使えるiPadを識別するプログラム
- 第92回 Swift Playgrounds 2.1での問題点をまとめて解消する
- 第91回 iPadの内蔵カメラで撮影した写真を認識するプログラム
- この連載の一覧へ