前回から進めているアプリ開発を、
バーゲン教師を作る
今回は、

パーツの配置と接続
バーゲン教師の画面構成と動作について説明します。画面上のパーツをより詳しく見ると、

まず、
(1)のテキストフィールドには数字を入力しますので、
パーツと接続するアウトレットおよびアクションの組み合わせは次の通りです。
- アウトレット
- priceOriginal - (1)テキストフィールド
- discountButton - (2)セグメンテッドコントロール
- discountPercent - (3)ラベル
- discountSlider - (4)スライダー
- priceNew - (5)ラベル
- cartPrice - (7)ラベル
- アクション
- buttonValueChanged: - (2)セグメンテッドコントロール / Value Changed
- sliderValueChanged - (4)スライダー / Value Changed
- escapeButtonPush: - (2)セグメンテッドコントロール / Value Changed 、
(4)スライダー / Value Changed - pushAddCart - (6)ボタン / Touch Down
- pushClearCart - (8)ボタン / Touch Down
これまでアクションの名前には最初から付いている
また、
上記の組み合わせをもとにInterface Builderを使ってパーツを配置し、
背景色は、
パーツの配置とラベルの入力、
アクションの実装
それでは、
- (IBAction)buttonValueChanged:(id)sender {
//割引率を保持する変数
float discount_value = 0.2f;
//セグメンテッドコントロールの選択位置から割引率を決定
int selected_index = [discountButton selectedSegmentIndex];
switch(selected_index){
case 0:
discount_value = 0.2f;
break;
case 1:
discount_value = 0.3f;
break;
case 2:
discount_value = 0.4f;
break;
case 3:
discount_value = 0.5f;
break;
default:
break;
}
//選択されている割引率の位置にスライダーのつまみを動かす
[discountSlider setValue:discount_value animated:YES];
//割引率をパーセント形式でラベルに表示
[discountPercent setText:[NSString stringWithFormat:@"%d", (int)(discount_value * 100.f)]];
//元値と割引率から割引後の値段を計算してラベルに表示
int price_original = [[priceOriginal text] intValue];
if(price_original > 0){
[priceNew setText:[NSString stringWithFormat:@"%d", (int)(price_original * (1.f - discount_value))]];
}
}
これはセグメンテッドコントロールで割引率が変更されたときのアクションです。discountButtonで選択されている番号をもとに割引率を小数で表し、
また、
- (IBAction)sliderValueChanged:(id)sender {
//スライダーの値から割引率を決定、0.5単位に切り捨てる
float discount_value = (int)([(UISlider*)sender value] * 20) / 20.f;
//セグメンテッドコントロールに一致する割引率があれば選択されている状態にする
if(discount_value == 0.2f){
[discountButton setSelectedSegmentIndex:0];
}
else if(discount_value == 0.3f){
[discountButton setSelectedSegmentIndex:1];
}
else if(discount_value == 0.4f){
[discountButton setSelectedSegmentIndex:2];
}
else if(discount_value == 0.5f){
[discountButton setSelectedSegmentIndex:3];
}
else{
[discountButton setSelectedSegmentIndex:-1];
}
//割引率をパーセント形式でラベルに表示
[discountPercent setText:[NSString stringWithFormat:@"%d", (int)(discount_value * 100.f)]];
//元値と割引率から割引後の値段を計算してラベルに表示
int price_original = [[priceOriginal text] intValue];
if(price_original > 0){
[priceNew setText:[NSString stringWithFormat:@"%d", (int)(price_original * (1.f - discount_value))]];
}
}
続いてはスライダーによって割引率が変更されたときのアクションです。スライダーでは5%から95%までの範囲を5%単位で選択しますので、
値が求まったら、
割引率が決定したらあとはセグメンテッドコントロールのときと同じように、
- (IBAction)escapeButtonPush:(id)sender {
[priceOriginal endEditing:YES];
}
これはキーボードを閉じるきっかけとなるパーツから呼び出されるアクションです。ここではセグメンテッドコントロールの値が変更された時とスライダーが変更された時にアクションが実行されるよう設定しましたが、
- (IBAction)pushAddCart:(id)sender {
[cartPrice setText:[NSString stringWithFormat:@"%d", [[priceNew text] intValue] + [[cartPrice text] intValue]]];
}
カートに追加するためのボタンが押された時のアクションは単純で、
- (IBAction)pushClearCart:(id)sender {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"カートをクリアしますか?" delegate:self cancelButtonTitle:@"キャンセル" destructiveButtonTitle:@"クリアする" otherButtonTitles:nil];
[actionSheet showInView:self.view];
[actionSheet release];
}
最後はカートをクリアするボタンが押されたときのアクションです。ダイアログを表示して、
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0){
//カートをクリアする
[cartPrice setText:[NSString stringWithFormat:@"%d", 0]];
}
}
このように、
動作テストとバグ
これでプログラムができあがりました。ビルドして動作を確認しましょう。
ここでなんとなく動いているからといって安心はできません。一見大丈夫そうに見えても、
しかしながら、
動作が複雑なアプリはそれだけテストに費やす時間も多くなる傾向にあります。使用するパーツの数が増えれば増えるほど、
バーゲン教師の動作テスト
バーゲン教師では次のようなテストを行ってみましょう。いずれも想定される基本操作にあたります。
- 金額が正しく入力できるか
- セグメンテッドコントロールのすべてのボタンが正しく動作するか
- スライダーが正しく動作するか
- 割引後の金額が正しく表示されるか
- カートへの追加が正しく行えるか
- カートが正しくクリアされるか
- カートクリア時のダイアログでキャンセルが正しく行えるか
- 一旦カートをクリアした後、
再度カートへの追加が正しく行えるか
バグがないことが確認できたら、
アイデアを形に
ここまできたら、
割勘奉行も中身は同じ
より多くのことを学ぼうとせずとも、

金額と人数のテキストフィールドにはキーボードを使って数字を入力しますが、
割勘奉行には、
プロジェクトをダウンロード
割勘奉行はソースコードを公開しています。プロジェクトのファイル一式をダウンロードするには、
svn checkout http://warikan.googlecode.com/svn/trunk/ warikan
ホームディレクトリ
自分なりのやり方で
プログラミングの勉強はひとまず今回で終わりです。XcodeやInterface Builderも随分と使いこなせるようになってきたことでしょう。パーツの使い方やプログラムの書き方を含め、
次回は、