【初心者向け】Objective-Cで5つの親子関係を扱う方法

Objective-Cのコード例とともにparentViewControllerを学ぶObjctive-C
この記事は約19分で読めます。

※本記事のコンテンツは、利用目的を問わずご活用いただけます。実務経験10000時間以上のエンジニアが監修しており、基礎知識があれば初心者にも理解していただけるように、常に解説内容のわかりやすさや記事の品質に注力しております。不具合・分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。(理解できない部分などの個別相談も無償で承っております)
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミングの世界において、Objective-Cは長年にわたってiOSアプリケーションの開発言語として重要な役割を果たしてきました。

特に、親子関係を管理する機能は、複数の画面を持つアプリケーションを作る上で欠かせないものです。

この記事を読めば、Objective-CでのparentViewControllerの使い方を5つのステップでマスターできるようになり、親ビューコントローラと子ビューコントローラを扱う基本的なスキルを身につけることができます。

この知識は、アプリ開発において、異なる画面間でのデータや命令の流れをスムーズに制御するのに役立ちます。

たとえば、ログイン画面からメインコンテンツへの移動や、設定画面からの情報の更新など、ユーザーインターフェイスの流れを作る際にこの知識が直接的に応用されます。

それでは、Objective-Cの基本からparentViewControllerの詳細な使い方までを、初心者でも理解しやすいように順を追って詳しく見ていきましょう。

●Objective-Cとは

Objective-Cは、C言語をベースにオブジェクト指向の機能を拡張したプログラミング言語です。

AppleのMac OS XやiOSのためのソフトウェア開発に主に使用され、Swiftに次ぐ人気を誇っています。

その特徴は、動的なタイプ指定とメッセージパッシングです。これにより、開発者は柔軟かつ強力なコードを書くことができます。

○Objective-Cの基本

Objective-Cを学ぶには、まず基本的な文法や構文を理解する必要があります。

変数の宣言、条件分岐、ループ、関数の作成といった基本的なプログラミングの概念はC言語と共通していますが、クラス、インターフェイス、継承、ポリモーフィズムといったオブジェクト指向の概念を学ぶことで、より強力なプログラミングが可能になります。

Objective-Cでは、ファイルは通常、ヘッダ(.h)ファイルと実装(.m)ファイルの2つに分けて管理されます。

ヘッダファイルではクラスのインターフェイスを宣言し、実装ファイルではその具体的な動作を定義します。

この分離により、コードの再利用性と保守性が高まります。

●parentViewControllerの基本

parentViewControllerは、Objective-Cにおいて、ビューコントローラ間の親子関係を管理するための重要なプロパティです。

iOSアプリケーションにおいてビューコントローラは、画面の内容を制御するオブジェクトであり、アプリケーションの様々な画面(ビュー)はビューコントローラによって管理されます。

この関係を理解し、適切に使いこなすことは、効率的なアプリケーション開発には不可欠です。

たとえば、アプリケーションにおいて、ユーザーが「設定」画面から「アカウント情報」画面へと進むとき、’設定’画面のビューコントローラは’アカウント情報’画面のビューコントローラのparentViewControllerとなります。

この階層的な関係は、ユーザーがナビゲーションを進むにつれて、情報がどのように伝達され、管理されるかを決定します。

ビューコントローラ間の関係を設定するには、特定のビューコントローラを別のビューコントローラの子として追加することにより行われます。

子ビューコントローラは、自分自身を親ビューコントローラにプレゼンテーションするか、またはナビゲーションスタックにプッシュされることによって親子関係を形成します。

この階層は、ユーザーインターフェイスの複雑さに応じて複数レベルにわたることがあります。

例えば、タブバーインターフェースを持つアプリケーションでは、各タブが異なるビューコントローラを持ち、これら全てがタブバーコントローラの子として扱われます。

各子ビューコントローラは自分の親が誰であるかを知る必要がある時、parentViewControllerプロパティを参照することで、その情報を取得することができます。

○parentViewControllerとは何か

parentViewControllerとは、UIViewControllerクラスのプロパティの一つで、現在のビューコントローラが提示されている親ビューコントローラへの参照を提供します。

これにより、ビューコントローラは自身がどの親ビューコントローラの下に存在するかを認識し、適切にその親ビューコントローラとのデータのやりとりやイベントのハンドリングを行うことができます。

○parentViewControllerの役割と重要性

parentViewControllerの役割は、ビューコントローラの階層構造を管理することにあります。

この階層構造は、アプリケーション内でのビューコントローラの関係を明確にし、どのビューコントローラが前面にあるか、どのように相互作用するかなどの情報を定義します。

親子関係を正しく設定し管理することで、開発者はユーザーが各ビュー間をナビゲートする際の経験を向上させることができます。

また、メモリ管理の観点からも、不要になったビューコントローラを適切に解放するためには、parentViewControllerの理解が不可欠です。

●Objective-CでparentViewControllerを使う方法

Objective-Cでのアプリケーション開発において、parentViewControllerを使用することで、ビューコントローラ間の親子関係を効率的に管理できます。

ここでは、基本的な親ビューコントローラの設定方法から、さまざまな応用例までを見ていきます。

親ビューコントローラを設定する最も一般的なシナリオは、ナビゲーションコントローラ内で新しいビューコントローラをプッシュする場合です。

このとき、新しいビューコントローラのparentViewControllerプロパティは自動的にナビゲーションコントローラを指すようになります。

しかし、カスタムビューコントローラを使う場合や、特定のコンテキストで親子関係をプログラム的に制御したい場合には、このプロパティを直接扱う必要があります。

○サンプルコード1:基本的な親ビューコントローラの設定

Objective-CでparentViewControllerを設定する基本的なコードは次の通りです。

// 子ビューコントローラを作成
UIViewController *childViewController = [[UIViewController alloc] init];

// 親ビューコントローラ内で子ビューコントローラをプレゼンテーションする
[self presentViewController:childViewController animated:YES completion:nil];

// この時点で、childViewControllerのparentViewControllerはselfになります

このコードでは、現在のビューコントローラ(self)が新しく作成した子ビューコントローラをモーダルとして表示しています。

モーダルプレゼンテーションが完了した時点で、childViewControllerのparentViewControllerプロパティは自動的にself(現在のビューコントローラ)を参照するようになります。

この関係はユーザーが「閉じる」ボタンをタップして子ビューコントローラを閉じると解除されます。

○サンプルコード2:parentViewControllerを使ったビューの切り替え

ビューの切り替えにparentViewControllerを使用する場合、次のようなコードが参考になります。

// 子ビューコントローラで親ビューコントローラにアクセスし、ビューを切り替える
[self.parentViewController dismissViewControllerAnimated:YES completion:^{
    // ビュー切り替え後の処理
}];

この例では、子ビューコントローラが自身を閉じ、その後に何かの処理を実行することを示しています。

dismissViewControllerAnimated:completion:メソッドは、モーダルビューコントローラを閉じるために使用されます。

completionブロック内では、ビューが閉じた後に必要な任意のコードを実行できます。

○サンプルコード3:parentViewControllerを活用したデータの受け渡し

Objective-Cでは、親ビューコントローラと子ビューコントローラ間でデータを受け渡すことが一般的な作業です。

この作業は、ユーザーが操作するときの応答性や、アプリケーションのフローをスムーズにするために不可欠です。

// ChildViewController.h
@interface ChildViewController : UIViewController

@property (strong, nonatomic) NSString *dataToPassBack;

@end

// ChildViewController.m
@implementation ChildViewController

// ボタンタップで呼び出されるメソッド
- (IBAction)returnDataToParent:(id)sender {
  if (self.parentViewController && [self.parentViewController respondsToSelector:@selector(receiveData:)]) {
    [self.parentViewController performSelector:@selector(receiveData:) withObject:self.dataToPassBack];
  }
}

@end

このコードスニペットでは、ChildViewControllerクラスにdataToPassBackプロパティを宣言し、ユーザーがボタンをタップするとそのデータを親ビューコントローラに渡すメソッドreturnDataToParent:を呼び出しています。

performSelector:withObject:メソッドを使用して、親ビューコントローラにデータを送ります。

この方法は、親ビューコントローラがreceiveData:メソッドを実装していることを確認した上で行われます。

○サンプルコード4:セグエを使った親子のナビゲーション

アプリケーションの異なるビュー間の移動は、セグエ(UIStoryboardSegue)を使用して行われることが多いです。

下記のコードは、セグエを使って別のビューへ移動し、データを渡すプロセスを表しています。

// ParentViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  if ([segue.identifier isEqualToString:@"showChildViewController"]) {
    ChildViewController *childVC = (ChildViewController *)segue.destinationViewController;
    childVC.dataToReceive = self.dataToPass;
  }
}

ここでは、prepareForSegue:sender:メソッド内で、セグエの識別子を確認し、適切な子ビューコントローラにデータを渡しています。

segue.destinationViewControllerは、セグエによって表示されるビューコントローラを参照します。

○サンプルコード5:parentViewControllerを使ったモーダルビューの管理

モーダルビューは、情報の詳細を表示したり、データ入力を受け取る際にしばしば使用されます。

ここではモーダルビューを管理する方法の一例を紹介します。

// モーダルビューコントローラを表示する
[self presentViewController:modalViewController animated:YES completion:nil];

// モーダルビューコントローラを閉じる
[modalViewController dismissViewControllerAnimated:YES completion:nil];

この例では、モーダルビューコントローラを表示するためにpresentViewController:animated:completion:メソッドを使い、閉じるときにはモーダルビューコントローラ自身のdismissViewControllerAnimated:completion:メソッドを使用しています。

モーダルビューが閉じられると、completionブロック内で指定した任意の後処理が実行されます。

●parentViewControllerの応用例

parentViewControllerの概念を理解することで、iOSアプリケーションの多くの面でその力を発揮することができます。

ここでは、Objective-CでのparentViewControllerの使用を超えた応用例を紹介します。

○サンプルコード6:複数の子ビューコントローラを持つタブバー

タブバーコントローラは一般に、複数の子ビューコントローラを管理するために使用されます。

これらのビューコントローラは、タブバーによってアクセスされ、ユーザーが異なるセクション間を簡単に切り替えられるようにします。

下記のコードは、タブバーコントローラのセットアップ方法を表しています。

// AppDelegate.m
UITabBarController *tabBarController = [[UITabBarController alloc] init];

UIViewController *viewController1 = [[UIViewController alloc] init];
viewController1.tabBarItem.title = @"First";

UIViewController *viewController2 = [[UIViewController alloc] init];
viewController2.tabBarItem.title = @"Second";

// タブバーコントローラにビューコントローラを設定
tabBarController.viewControllers = @[viewController1, viewController2];

self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];

このコードでは、2つのビューコントローラを初期化し、それぞれタブバーコントローラのアイテムとして追加しています。

タブバーアイテムのタイトルを設定することで、ユーザーがタブバーを通じて各ビューコントローラにアクセスできるようになります。

○サンプルコード7:parentViewControllerを使ったカスタムイベントの伝播

子ビューコントローラから親ビューコントローラへのイベント伝播は、次のように実装することができます。

// ChildViewController.m
- (void)customEventTrigger {
    // 親ビューコントローラにイベントを通知
    if ([self.parentViewController respondsToSelector:@selector(customEventHandler:)]) {
        [self.parentViewController performSelector:@selector(customEventHandler:) withObject:nil];
    }
}

// ParentViewController.m
- (void)customEventHandler:(id)sender {
    // カスタムイベントの処理をここで実施
}

このコードスニペットでは、ChildViewControllerが特定のイベント(例えば、ボタンのタップなど)をトリガーとして、parentViewControllerに定義されたcustomEventHandler:メソッドを呼び出しています。

これにより、子ビューコントローラが親ビューコントローラへのメッセージパッシングを行うことができます。

○サンプルコード8:継承を使ったparentViewControllerの拡張

Objective-Cでは、クラスの継承を使用して、既存のビューコントローラの機能を拡張することが一般的です。

下記の例は、カスタムビューコントローラがparentViewControllerのメソッドをオーバーライドして、追加の機能を提供する方法を表しています。

// CustomViewController.h
@interface CustomViewController : UIViewController
@end

// CustomViewController.m
@implementation CustomViewController

// 親クラスのメソッドをオーバーライド
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    // 追加のセットアップやイベントトラッキングをここで実施
}

@end

このコードでは、CustomViewControllerviewDidAppear:メソッドをオーバーライドしており、親クラスの実装を呼び出した後に、追加の処理を行うことができます。

これにより、カスタムビューコントローラは、その表示が完了した際に特定のアクションを実行することが可能になります。

●注意点と対処法

Objective-Cを使用したiOSアプリケーション開発において、parentViewControllerを扱う際にはいくつかの注意点があります。

これらの点を理解し、適切に対処することで、多くの一般的な問題を回避することができます。

○適切なparentViewControllerの使用

parentViewControllerは、ビューコントローラの階層を管理するための強力なツールですが、誤用すると予期しない動作やクラッシュを引き起こす原因となります。

たとえば、ビューコントローラが親ビューコントローラの存在を前提としている場合、その親が存在しない状況でメソッドを呼び出すとエラーが発生します。

このような問題を防ぐためには、常にparentViewControllerの存在を確認するコードを書くべきです。

if (self.parentViewController) {
    // 安全にparentViewControllerを使用する
}

○一般的なエラーとその対処法

parentViewControllerを使用する際によくあるエラーは、nilチェックを怠ったり、間違った型のオブジェクトを想定してメソッドを呼び出したりすることです。

これらのエラーを避けるためには、isKindOfClass:メソッドを使用してオブジェクトの型を確認することが役立ちます。

if ([self.parentViewController isKindOfClass:[SomeSpecificViewController class]]) {
    // parentViewControllerが特定のクラスのインスタンスであることを確認した後に処理を行う
}

○メモリ管理に関する注意点

Objective-Cにおけるメモリ管理は、特に親子ビューコントローラ間での参照を扱う場合に注意が必要です。

親ビューコントローラが解放されるときに、子ビューコントローラも適切に解放されるよう管理する必要があります。

ARC(Automatic Reference Counting)を使用している場合、通常はこれによって適切にメモリ管理が行われますが、循環参照には注意を払う必要があります。

delegateパターンを使用するときやブロックを使用するときには、特にweak参照を使用して循環参照を避けるべきです。

●カスタマイズ方法

Objective-CでのparentViewControllerのカスタマイズは、アプリケーションに独自の機能やユーザーインターフェイスを提供するための重要な手段です。

ここでは、いくつかの具体的なカスタマイズ方法をサンプルコードと共に解説します。

○parentViewControllerのカスタマイズ例

カスタマイズの最も一般的な形は、ビューコントローラのサブクラスを作成し、必要なメソッドやプロパティを追加することです。

例えば、特定の子ビューコントローラが常に親ビューコントローラにデータを通知する必要がある場合、カスタムデリゲートプロトコルを実装することができます。

下記のサンプルコードは、カスタムデリゲートプロトコルの定義と、そのプロトコルを使用して子ビューコントローラから親ビューコントローラへデータを送信する方法を表しています。

// CustomChildViewController.h
@protocol CustomChildViewControllerDelegate <NSObject>
- (void)childViewControllerDidUpdateData:(id)data;
@end

@interface CustomChildViewController : UIViewController
@property (weak, nonatomic) id<CustomChildViewControllerDelegate> delegate;
@end
// CustomChildViewController.m
@implementation CustomChildViewController
- (void)updateData {
    [self.delegate childViewControllerDidUpdateData:updatedData];
}
@end

そして、このデリゲートを親ビューコントローラ内で実装し、子ビューコントローラが更新を行うたびに反応するようにします。

// ParentViewController.m
#import "CustomChildViewController.h"

@interface ParentViewController () <CustomChildViewControllerDelegate>
@end

@implementation ParentViewController

- (void)childViewControllerDidUpdateData:(id)data {
    // 子ビューコントローラからのデータ更新に対応する処理
}

@end

このパターンを使用することで、ビューコントローラ間の通信を明確にし、カスタムイベントの処理を容易にすることができます。

デリゲートメソッドは、子ビューコントローラが親ビューコントローラにデータを渡す際のハンドラとして機能します。

まとめ

この記事では、Objective-Cの基本からparentViewControllerの使い方、応用例に至るまでの幅広い内容を網羅的に説明しました。

初心者にも理解しやすいように、基本的な概念から段階を追って説明し、サンプルコードを多用して実際の使用方法を紹介しました。

本ガイドを通じて、読者がObjective-CのparentViewControllerに関する包括的な理解を深め、自身のプロジェクトに活かすことを願います。

プログラミングは継続的な学習プロセスであり、本記事がその一助となれば幸いです。

Objective-Cによるアプリケーション開発は多くの可能性を秘めており、この言語の深い理解はあなたのスキルセットを大きく拡張することでしょう。