インターフェイスファイルに書いたIBOutletとIBActionが、XcodeとInterface Builderの架け橋です。先頭の「IB」はInterface Builderを意味し、宣言にこれらの記述があるインスタンス変数、メソッドはInterface Builderから扱えるようになります。
Interface BuilderのBMICalcViewController.xibウィンドウで[Files Owner]を選択します。
Inspectorの[Connections]を選択すると、[Outlets]に「BMICalcViewController.h」でIBOutlet付きで宣言したインスタンス変数がすべて表示されています。[heightLabel]の右側の○をドラッグすると、青い線が現れます。この線をプレビュー画面の「身長」テキストフィールドにドロップして接続しましょう。
これだけで、Xcodeで書いた変数から、Interface Builderで作成したテキストフィールドオブジェクトが参照されるようになります。同様に、ほかのOutletも対応するUI部品と線でつないでいきましょう。
インターフェイスファイルで、「(IBAction)」を付けて宣言したメソッドは、Inspectorの[Connections]→[Received Action]に表示されているはずです。[executeCalc]の右の○をドラッグし、青い線を「計算」ボタンにドロップします。
すると、以下のように選択ダイアログが開きます。
これらはボタンに対してユーザーが行える操作(イベント)の一覧です。今回は「タッチされたとき」を意味する[Touch Down]を選択します。これで、「計算」ボタンがタッチされると、executeCalcメソッドが実行されるようになります。同様に、executeResetメソッドを「リセット」ボタンの[Touch Down]に接続します。
さて、「これで完成」といきたいところですが、このアプリにはまだ欠陥があります。いったん保存して、Xcodeで[ビルドと実行]を行ってみましょう。
起動したBMI計算アプリに身長と体重を入力して計算ボタンを押すと、処理は動いているようですが、キーボードが表示されたままで結果が見えません。
この問題を解決するために、キーボードの[return]ボタンが押されるか、「計算」または「リセット」ボタンが押されたら、キーボードを隠してやる必要があります。
テキストフィールドで[return]が押されたときのイベントを処理するには、「Delegate(デリゲート)」という仕組みを使います。日本語にすると「委譲」で、要は「ほかの人に任せる」ということです。
Cocoa Touchフレームワークには、テキストフィールドの処理を委譲するためのプロトコル[UITextFieldDelegate]が用意されています。BMICalcViewController.hで以下のように[UITextFieldDelegate]を実装することを宣言します。
@interface BMICalcViewController : UIViewController<UITextFieldDelegate> {
次に、実装ファイルBMICalcViewController.mに移り、UITextFieldDelegateのtextFieldShouldReturnメソッドを実装します。これは、テキストフィールドで[return]が押された場合に実行されるイベントメソッドです。これで、BMICalcViewControllerクラスがテキストフィールドのイベントを処理できるようになります。
// 身長・体重テキストのキーボードを隠す処理 - (void)textFieldResignFirstResponder { [heightText resignFirstResponder]; [weightText resignFirstResponder]; } // UITextFieldDelegateプロトコルで定義されているイベントメソッド // キーボードのReturnキーが押された後に呼ばれる - (BOOL)textFieldShouldReturn:(UITextField *)textField { [self textFieldResignFirstResponder]; return YES; }
また、[return]を押さずに、直接「計算」ボタン、「リセット」ボタンが押された場合にもキーボードが隠れるように、executeCalcとexecuteResetメソッドの最初にもキーボードを隠す処理を追加します。
なお、ここでのtextFieldResignFirstResponderメソッドはインターフェイスファイルで宣言していないため、executeCalcやexecuteResetよりも前の行で宣言するように注意してください。
// 計算ボタンの Touch Down イベントに登録するBMI計算実行処理 - (IBAction)executeCalc:(id) sender { // キーボードを隠す [self textFieldResignFirstResponder]; // 身長テキストフィールドに入力された値(cm)をメートルに変換 float height = [heightText.text floatValue]/100; // 体重テキストフィールドに入力された値を取得 float weight = [weightText.text intValue]; // BMI = 体重(kg)÷ (身長(m) × 身長(m)) float bmi = weight / (height * height); // BMI計算結果(小数点第1位まで) NSString *bmiStr = [ NSString stringWithFormat: @"%.1f", bmi ]; // 標準体重(kg) = 身長(m) × 身長(m) × BMI標準値(22) float stdWeight = (height * height) * 22; // 標準体重の計算結果(小数点第1位まで)を、標準体重ラベルに設定 NSString *stdWeightStr = [ NSString stringWithFormat: @"%.1f", stdWeight ]; // 結果判定を行う NSString *result = @""; // BMIが18.51より小さければ、[やせ気味] if (bmi < 18.5) { result = @"[やせ気味]です。"; // BMIが18.5以上、25より小さければ、[理想の体重] } else if (bmi >= 18.5 && bmi < 25) { result = @"[理想の体重]です。"; // それ以上の場合は、[肥満] } else { result = @"[肥満]です。"; } // 判定結果を結果ラベルに設定 resultLabel.text = [NSString stringWithFormat:@"%@%@%@%@%@%@", @"BMI\n", bmiStr, @"\n\n標準体重\n", stdWeightStr, @"kg\n\n", result]; }
次に、Interface Builderでテキストフィールドの委譲先をBMICalcViewControllerに指定します。「身長」テキストフィールドを選択し、[Inspector]の[Connections]→[delegate]の右の○をドラッグして、[Files' Owner]であるBMICalcViewControllerにつなぎます。これで、「身長」テキストフィールドのイベント処理はBMICalcViewControllerクラスに任されることになります。
同様に、「体重」テキストフィールドの[delegate]もBMICalcControllerにつなぎましょう。
Interface Builderでの作業を保存したら、Xcodeから[ビルドと実行]を行い、アプリを起動して使ってみましょう。今度は、結果が隠れずに表示されるはずです。
今回は、1画面から構成されるアプリの作成を通して、Interface Builderを利用したUI設計と、イベント処理について解説しました。また、テキストフィールドの[return]キーイベントを処理するために利用したDelegateはCocoa Touchフレームワークのイベント処理の基本となる考え方です。Cocoa Touchフレームワークの提供するさまざまなDelegateプロトコルを使いこなせると、より柔軟な実装が可能となるでしょう。
次回は、このアプリの実装を例に、開発の際に必ず必要となるデバッグ方法やメモリリーク発見方法・アプリの多言語対応、などについて説明していきたいと思います。どうぞお楽しみに。
サンプル完成版のソースコードは、こちらからダウンロードできます。
竹内 彰吾(たけうち しょうご)
どこにでもいる職業プログラマであり、好きな言語はJavaとObjective-C。現在は、業務システムの開発に従事し、顧客の要望に日々全力で応えている。
一方、ほかの案件や趣味ではiPhone/Androidアプリ開発にも積極的に取り組んでいる
Copyright © ITmedia, Inc. All Rights Reserved.