【Objective-C】UIPopoverPresentationControllerの使い方9選

プログラミングの初心者がObjective-CでUIPopoverPresentationControllerを使ってみた例のイメージObjctive-C
この記事は約26分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミングに初挑戦する方でも、Objective-Cを使ったUIPopoverPresentationControllerの作成は難しくありません。

この記事では、Popoverとは何か、そしてその魅力的な特徴から、基本的な使用法、カスタマイズ方法、そして実際のエラー対処法までを9つの具体的な例とともに学べます。

この記事を読み終える頃には、あなたもPopoverを自在に扱えるようになり、iOSアプリケーションのユーザーインターフェースを豊かにする方法を掌握していることでしょう。

●UIPopoverPresentationControllerとは

UIPopoverPresentationControllerは、iPadで主に使用されるUIコンポーネントで、ユーザーがあるアクションを行った際に小さいウィンドウを表示することができます。

このウィンドウは「ポップオーバー」と呼ばれ、アプリケーションの流れを妨げることなく追加情報や選択肢を提示するのに適しています。

例えば、ユーザーがボタンをタップしたときにフォームやメニューを表示したり、設定を変更するオプションを提供したりする際に使われます。

○UIPopoverPresentationControllerの役割とは

ポップオーバーは情報の階層をフラットに保ちつつ、追加のコンテンツへのアクセスを直感的に行う手段です。

これにより、ユーザーは現在のコンテキストを離れることなく、必要な作業を素早く行うことができます。

モーダルウィンドウとは異なり、ポップオーバーは背後のコンテンツをブロックせず、ユーザーがポップオーバー以外の領域をタップすることで簡単に閉じることができます。

○UIPopoverPresentationControllerのメリット

UIPopoverPresentationControllerを使用する最大の利点は、その柔軟性にあります。

位置、サイズ、そして表示内容を開発者が自由に定義できるため、アプリのデザインと機能性を向上させることができます。

また、デバイスが縦向きか横向きかに関わらず、適切なレイアウトを維持する機能があり、ユーザーエクスペリエンスを向上させます。

●UIPopoverPresentationControllerの基本的な使い方

UIPopoverPresentationControllerを使用する際の基本的な手順は、まずPopoverを表示するためのビューコントローラーを作成し、その後に表示するコンテンツのサイズと位置を設定することです。

Objective-Cでの実装では、通常、アクションやボタンのイベントに応じてPopoverを表示させるコードを記述します。

iOSではユーザーの操作に対応して動的にコンテンツを表示することが一般的であり、UIPopoverPresentationControllerはそのための理想的なツールの一つです。

○基本的な設定方法

UIPopoverPresentationControllerを使うには、次のようなステップが必要です。

  1. 表示するコンテンツを管理するビューコントローラーを定義します。
  2. UIPopoverPresentationControllerオブジェクトを作成し、このビューコントローラーをモーダルプレゼンテーションスタイルとして設定します。
  3. ポップオーバーのデリゲートを設定して、ポップオーバーが適切に動作するようにします。
  4. ポップオーバーが指し示すべき元となるビューまたはバーボタンアイテムを指定します。
  5. 必要に応じてポップオーバーの外見をカスタマイズします。
  6. 最後に、ビューコントローラーを表示します。

これらの手順に従って、初心者でも簡単にPopoverを作成し、自分のアプリに組み込むことができるようになります。

○サンプルコード1:基本的なPopoverの作成

ここではObjective-Cを使用してUIPopoverPresentationControllerで基本的なPopoverを作成するためのサンプルコードを紹介します。

// ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

- (IBAction)showPopover:(id)sender;

@end

// ViewController.m
#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) UIPopoverPresentationController *popoverController;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // その他の初期化コード
}

- (IBAction)showPopover:(id)sender {
    // 表示するコンテンツのビューコントローラーを作成
    UIViewController *contentViewController = [[UIViewController alloc] init];
    // コンテンツのサイズを設定
    contentViewController.preferredContentSize = CGSizeMake(200, 300);

    // ポップオーバーのプレゼンテーションコントローラーを設定
    self.popoverController = contentViewController.popoverPresentationController;
    self.popoverController.delegate = self;
    // ポップオーバーが指し示すビューを設定
    self.popoverController.sourceView = self.view;
    self.popoverController.sourceRect = [sender frame];

    // ポップオーバーを表示
    [self presentViewController:contentViewController animated:YES completion:nil];
}

// UIPopoverPresentationControllerDelegateのメソッドを実装
// ...(デリゲートメソッドの実装)

@end

このコードでは、showPopoverメソッドがボタンのアクションにリンクされており、ボタンをタップするとPopoverが表示されます。

contentViewControllerはPopoverに表示される内容を管理し、sourceViewとsourceRectはPopoverが指し示す元のビューと位置を指定しています。

このサンプルコードを実行すると、画面上のボタンをタップすると、設定したサイズのPopoverが表示されます。

このPopoverはユーザーが他の場所をタップすると閉じられるため、使い勝手の良いユーザーインターフェースを提供できます。

●UIPopoverPresentationControllerのカスタマイズ方法

UIPopoverPresentationControllerはiOSアプリケーションでポップオーバーを管理するためのクラスです。

これは、iPadアプリケーションにおいて特に有用であり、モーダルビューや情報の一部を一時的に表示する際に使用されます。

カスタマイズ性が高く、多くの属性が変更可能であるため、デザイナーや開発者はアプリケーションのブランドやデザインに合わせたポップオーバーを作成することができます。

○サイズの変更方法

UIPopoverPresentationControllerのサイズを変更するには、preferredContentSizeプロパティを設定することで、表示するビューコントローラーのサイズを調整できます。

サイズ変更はユーザーのニーズに合わせて、情報量やUIの要素に応じて行うことが望ましいです。

たとえば、テキストが少ない通知であれば小さなサイズが適しているかもしれませんし、フォーム入力や詳細情報の表示には大きなサイズが必要になるでしょう。

○サンプルコード2:サイズをカスタマイズしたPopover

下記のサンプルコードは、UIPopoverPresentationControllerを使用してカスタムサイズのポップオーバーを作成する方法を表しています。

// カスタムサイズのポップオーバーを表示するためのViewControllerを準備
UIViewController *popoverContentController = [[UIViewController alloc] init];
popoverContentController.preferredContentSize = CGSizeMake(300, 300); // 幅300pt、高さ300ptに設定

// ポップオーバーの設定
UIPopoverPresentationController *popover = popoverContentController.popoverPresentationController;
popover.permittedArrowDirections = UIPopoverArrowDirectionAny; // 任意の方向に矢印を許可
popover.sourceView = self.view; // このViewを基点に表示
popover.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds),0,0); // 中央に表示

// ポップオーバーを表示
[self presentViewController:popoverContentController animated:YES completion:nil];

このコードでは、まずUIViewControllerのインスタンスを作成し、そのpreferredContentSizeプロパティをCGSizeMakeメソッドを用いて300pt x 300ptと指定しています。

これによりポップオーバーのサイズが300ptの正方形になります。

UIPopoverPresentationControllerの設定では、permittedArrowDirectionsプロパティを用いて矢印が表示される方向を指定し、sourceViewとsourceRectを設定することで、ポップオーバーが表示される基点となるViewの位置とサイズを定めています。

最後に、presentViewControllerメソッドを呼び出してポップオーバーを画面に表示しています。

このコードの実行結果は、画面中央に基点を置き、任意の方向に矢印が指し示された300pt x 300ptのカスタムサイズのポップオーバーが表示されることになります。

○矢印の方向の変更

ポップオーバーの矢印の方向は、ユーザーの体験を向上させるためにも重要な要素です。

UIPopoverPresentationControllerでは、permittedArrowDirectionsプロパティを変更することで、矢印の方向を制御することができます。

例えば、特定のボタンやアクションを強調するために矢印をその方向にだけ表示させたい場合などに有用です。

○サンプルコード3:矢印の方向をカスタマイズしたPopover

下記のサンプルコードは、UIPopoverPresentationControllerの矢印の方向をカスタマイズする方法を表しています。

// 矢印の方向をカスタマイズするためのViewControllerの設定
UIViewController *customArrowDirectionPopover = [[UIViewController alloc] init];
customArrowDirectionPopover.preferredContentSize = CGSizeMake(200, 200); // サイズを設定

// ポップオーバーの設定
UIPopoverPresentationController *arrowCustomizedPopover = customArrowDirectionPopover.popoverPresentationController;
arrowCustomizedPopover.permittedArrowDirections = UIPopoverArrowDirectionUp; // 矢印の方向を上に限定
arrowCustomizedPopover.sourceView = self.view; // このViewを基点に表示
arrowCustomizedPopover.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMaxY(self.view.bounds),0,0); // Viewの上部に表示

// ポップオーバーを表示する
[self presentViewController:customArrowDirectionPopover animated:YES completion:nil];

このコードでは、UIViewControllerの新しいインスタンスを作成しており、そのpreferredContentSizeを200pt四方のサイズで設定しています。

ポップオーバーの矢印の方向をUIPopoverArrowDirectionUpで上方向に限定しており、sourceViewとsourceRectを設定することでポップオーバーが表示される位置を制御しています。

このコードを実行すると、指定したViewの上部に矢印が上向きで表示されるポップオーバーが現れます。

●UIPopoverPresentationControllerの応用例

UIPopoverPresentationControllerを用いた応用例は、その多機能性から様々なシーンで活用できます。

たとえば、コンテキストメニューやヘルプテキストを表示する際に、簡単な操作で豊かなユーザー体験を提供することが可能です。

また、Popoverを利用してフォーム入力を要求するウィンドウや、操作ガイドを提供する場面でも見かけます。

ここでは、これらの応用例に沿ったサンプルコードを交えながら、具体的な実装方法を解説します。

○サンプルコード4:コンテンツに合わせたPopover

UIPopoverPresentationControllerを活用して、表示するコンテンツの量に基づいてPopoverのサイズを動的に変更する例を考えてみましょう。

下記のサンプルコードは、コンテンツの高さに合わせてPopoverの高さが調整されるように実装されています。

// コンテンツに合わせたPopoverのViewControllerを作成
UIViewController *dynamicSizePopoverController = [[UIViewController alloc] init];
// ここでコンテンツのサイズを計算するロジックを追加する
CGSize contentSize = [self calculateContentSizeForMyContent]; // 仮の関数を用いる
dynamicSizePopoverController.preferredContentSize = contentSize;

// ポップオーバーの設定
UIPopoverPresentationController *popover = dynamicSizePopoverController.popoverPresentationController;
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
popover.sourceView = self.view; // このViewを基点に表示
popover.sourceRect = [self sourceRectForMyView]; // 仮の関数を用いる

// ポップオーバーを表示
[self presentViewController:dynamicSizePopoverController animated:YES completion:nil];

このコードでは、calculateContentSizeForMyContent関数を仮に作成しており、実際にはコンテンツのサイズに基づいてPopoverのサイズを計算するロジックが含まれていることを想定しています。

sourceRectForMyView関数も同様に、Popoverを表示するビューの位置を決定するために仮設されています。

実際にこれらの関数を実装する際には、表示するコンテンツの大きさや位置を計算し、それに応じてPopoverのpreferredContentSizesourceRectを設定します。

このコードを実行すると、指定されたコンテンツに応じたサイズのPopoverが表示され、動的なコンテンツ表示に対応できるようになります。

○サンプルコード5:複数のビューでPopoverを再利用

アプリケーション内で異なるビューから同じPopoverを呼び出すことは一般的なシナリオです。

下記のサンプルコードは、再利用可能なPopoverを構築する方法を表しています。

// 再利用可能なPopoverのViewControllerを作成
UIViewController *reusablePopoverController = [self createReusablePopoverContentController]; // 仮の関数を用いる

// ポップオーバーを複数のビューで再利用するための設定
UIPopoverPresentationController *popover = reusablePopoverController.popoverPresentationController;
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
popover.sourceView = self.currentActiveView; // 現在アクティブなViewを基点に表示する
popover.sourceRect = self.currentActiveView.bounds; // アクティブなViewのboundsを基点とする

// ポップオーバーを表示
[self presentViewController:reusablePopoverController animated:YES completion:nil];

createReusablePopoverContentController関数は、Popoverの内容を設定する部分で、実際にはアプリケーションの要件に応じたViewControllerを返す実装が必要です。

currentActiveViewプロパティは、現在ユーザーが操作しているビューを指すもので、これにより同じPopoverを異なるビューに対して適切に表示することができます。

このコードを実行すると、アプリケーション内のどのビューからでも同じPopoverを呼び出せるようになり、コードの再利用性が高まります。

○サンプルコード6:フォーム入力用のPopover

ユーザーにフォーム入力を促すためのPopoverを作成することは、ユーザーインターフェースの一部として非常に有効です。

下記のコードは、フォーム入力用のPopoverを表示する一例です。

// フォーム入力用のPopoverを構築するためのViewControllerを準備
UIViewController *formInputPopoverController = [[UIViewController alloc] initWithNibName:@"FormInputView" bundle:nil]; // フォーム入力ビューのXIBを使用

// ポップオーバーの設定
UIPopoverPresentationController *popover = formInputPopoverController.popoverPresentationController;
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
popover.sourceView = self.view; // このViewを基点に表示
popover.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds),0,0); // 中央に表示

// ポップオーバーを表示
[self presentViewController:formInputPopoverController animated:YES completion:nil];

ここで、initWithNibNameメソッドを使用して、事前にデザインされたXIBファイルからフォーム入力ビューをロードしています。

このビューは、ユーザーが情報を入力するためのテキストフィールドやボタンを含むカスタムビューです。

Popoverの表示位置として中央を選んでいますが、これはユーザーの注意を直接引きつけるための一般的な選択です。

このコードを実行すると、アプリケーションの中央にフォーム入力用のPopoverが表示され、ユーザーは直感的に情報を入力することが可能になります。

これにより、アプリケーションはユーザーに対して明確なアクションを提案できると同時に、ユーザー体験を向上させることができます。

●UIPopoverPresentationControllerを使ったエラー処理とその対策

エラー処理は、アプリケーション開発において不可欠な部分です。

UIPopoverPresentationControllerを用いた場合、エラーが発生した時にユーザーに情報を提供することで、より良いユーザーエクスペリエンスを提供することが可能です。

例えば、フォームのバリデーションエラーをPopoverで表示したり、ネットワークの接続エラーを通知したりすることができます。

ここでは、特定のエラーが発生した場合にPopoverを使用してエラーメッセージを表示する方法を説明します。

○よくあるエラーとその原因

UIPopoverPresentationControllerの実装においては、様々なエラーが発生する可能性があります。

例えば、内容が表示される前にPopoverが閉じられた場合や、配置が不適切で正しく表示されない場合などです。

これらのエラーの一般的な原因は、次のとおりです。

  1. コンテンツが読み込まれる前にPopoverがディスミスされる。
  2. sourceViewやsourceRectが不適切に設定されているため、Popoverが期待する位置に表示されない。
  3. ユーザーインタフェースの設計が不適切で、Popoverの矢印が指す方向がビューの範囲外になっている。

これらの問題を解決するためには、適切なエラーチェックとユーザーへのフィードバックが必要です。

○サンプルコード7:エラー処理を含むPopover

下記のサンプルコードは、UIPopoverPresentationControllerを使ったエラー処理の実装方法を表しています。

// エラーを表示するためのPopoverViewControllerを作成
UIViewController *errorPopoverController = [[UIViewController alloc] init];
errorPopoverController.preferredContentSize = CGSizeMake(280, 140); // 適切なサイズに設定
errorPopoverController.view.backgroundColor = [UIColor whiteColor];

// エラーメッセージを表示するためのラベルを設定
UILabel *errorLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 240, 100)];
errorLabel.text = @"エラーメッセージをここに表示";
errorLabel.numberOfLines = 0; // 複数行のテキストを許可
[errorPopoverController.view addSubview:errorLabel];

// エラーを表示するPopoverの設定
UIPopoverPresentationController *popover = errorPopoverController.popoverPresentationController;
popover.permittedArrowDirections = UIPopoverArrowDirectionUnknown; // 矢印の方向を指定しない
popover.sourceView = self.view; // このViewを基点に表示
popover.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds),0,0);

// ポップオーバーが表示できるかどうかを確認し、表示できない場合はエラーログを出力
if (popover) {
    [self presentViewController:errorPopoverController animated:YES completion:nil];
} else {
    NSLog(@"Popoverを表示できません。sourceViewまたはsourceRectが不適切か、すでに別のPopoverが表示されている可能性があります。");
}

このコードでは、UILabelを使用してエラーメッセージを表示するシンプルなViewControllerを準備しています。

設定されたテキストは例示的なものであり、実際のエラーメッセージに応じて変更されるべきです

また、エラーが発生したときには、NSLogを使用してコンソールにエラーメッセージを出力しています。これにより、開発中やデバッグ時に問題を迅速に特定できます。

実行すると、このコードはエラーメッセージを含むPopoverを画面に表示し、何らかの理由でPopoverが表示できない場合は、開発者にその旨を通知します。

●UIPopoverPresentationControllerのデザインカスタマイズ

アプリケーションの魅力を高めるためには、UIPopoverPresentationControllerのデザインカスタマイズが有効です。

ユーザーが視覚的に魅力を感じるデザインは、使用体験を向上させるだけでなく、アプリケーションの品質を象徴する要素ともなります。

カスタマイズは、色調の調節からフォントの変更、影の追加に至るまで多岐にわたります。

ここでは、背景色のカスタマイズとポップオーバーにアニメーション効果を加える方法を解説します。

○背景色のカスタマイズ方法

Popoverの背景色を変更することは、ポップオーバーの外観に即座に影響を与える最も簡単な方法の一つです。

背景色は、その内容の性質や状況に合わせて選択されるべきです。

たとえば、警告やエラーメッセージを表示する際は赤やオレンジ色を、情報メッセージには青や緑色を使用することが一般的です。

○サンプルコード8:背景色を変更したPopover

UIPopoverPresentationControllerの背景色を変更するには、下記のコードスニペットを参考にしてください。

// 背景色をカスタマイズするPopoverViewControllerを作成
UIViewController *customBackgroundColorPopoverController = [[UIViewController alloc] init];
customBackgroundColorPopoverController.preferredContentSize = CGSizeMake(200, 200);

// PopoverViewControllerの背景色を変更する
UIView *customBackgroundView = [[UIView alloc] initWithFrame:customBackgroundColorPopoverController.view.bounds];
customBackgroundView.backgroundColor = [UIColor colorWithRed:0.98 green:0.92 blue:0.84 alpha:1.0]; // カスタム色
[customBackgroundColorPopoverController.view addSubview:customBackgroundView];

// Popoverの設定
UIPopoverPresentationController *popoverController = customBackgroundColorPopoverController.popoverPresentationController;
popoverController.permittedArrowDirections = UIPopoverArrowDirectionAny;
popoverController.sourceView = self.view;
popoverController.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds),0,0);

// Popoverを表示
[self presentViewController:customBackgroundColorPopoverController animated:YES completion:nil];

このコードでは、UIViewControllerのインスタンスを生成し、そのViewの背景色をカスタム色に変更しています。

その後、設定された色のViewをPopoverViewControllerの最下層に追加し、Popoverの背景として機能させています。

この手法により、Popoverの外観をアプリケーションのテーマに合わせて調整することができます。

○ポップオーバーのアニメーション効果

ユーザーの注意を引きつけたり、操作のフィードバックを提供するためには、Popoverにアニメーションを追加することが効果的です。

例えば、Popoverが表示される際にフェードインするか、または拡大しながら現れるようなアニメーションが考えられます。

○サンプルコード9:アニメーション効果を加えたPopover

Popoverの表示にアニメーションを加えるには、下記の方法でUIViewのアニメーションAPIを使用します。

// アニメーション効果を持つPopoverViewControllerの作成
UIViewController *animatedPopoverController = [[UIViewController alloc] init];
animatedPopoverController.preferredContentSize = CGSizeMake(250, 250);

// PopoverViewControllerの準備ができたら、アニメーションを追加して表示
UIPopoverPresentationController *popover = animatedPopoverController.popoverPresentationController;
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
popover.sourceView = self.view;
popover.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds),0,0);

// Popoverのビューにカスタムアニメーションを設定
animatedPopoverController.view.alpha = 0.0; // 初期状態は透明
animatedPopoverController.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.6, 0.6); // 初期状態は縮小されている

[self presentViewController:animatedPopoverController animated:NO completion:^{
    [UIView animateWithDuration:0.3 animations:^{
        animatedPopoverController.view.alpha = 1.0; // フェードイン
        animatedPopoverController.view.transform = CGAffineTransformIdentity; // 元のサイズに戻る
    }];
}];

このコードを実行すると、Popoverがフェードインしながら元のサイズに戻るアニメーションとともに表示されます。

アニメーションの期間や変換の程度は、アプリケーションの要件やデザインに合わせて調整することができます。

まとめ

この記事を通じて、基本的なPopoverの生成からカスタマイズ、応用例、さらにはエラー処理に至るまでの多岐にわたる側面を詳細に解説しました。

今回提供した9つの例を通して、初心者はObjective-Cの基礎を固め、UIPopoverPresentationControllerを使いこなすスキルを身につけることができるでしょう。

プログラミングは継続的な学習プロセスであり、この記事がその一環として役立つことを願っています。