第03講 ドル円換算機
印刷を御希望の方はページ一番下の「印刷用ページ」より印刷してください。
PDFファイルとして保存したい場合も「印刷用ページ」より保存できます。
見出しに「★」マークがついた箇所は説明動画がございます。
★第3講のポイント
- 変数(小数・真偽値)の概念を理解する
- キーボードによるテキスト入力の手法を理解する
- 小数の計算手法や扱い方について理解する
- デバッグの概念を理解する
はじめに
前回の「カウンター」では変数の基礎や条件分岐を扱ってきました。第3講では少し内容を発展させて、小数の扱い方、小数同士の計算について議論していきます。さらに、キーボードによるテキスト入力等も扱います。
第3講の課題アプリは「ドル円換算機」となります。ある金額(ドル、または円)を入力すると、指定した変換レートに応じてもう一方の通貨に変換されるものです。
それでは、早速開発を始めて行きましょう!
プロジェクトの立ち上げと設定
新しいアプリを作る際は、まず、新規プロジェクトを立ち上げとアプリの設定を行います。
新規プロジェクトの立ち上げ
第1講と同じ要領で、新規プロジェクトを立ち上げます。その際、使用するテンプレートは「Single View Application」となります。
Product Name |
DollarYen |
Company Identifier |
com.rainbowapps |
Device Family |
iPhone |
Use Storyboard |
チェックを入れる |
Use Automatic Reference Counting |
チェックを入れる |
Include Unit Tests |
チェックを入れる
|
アプリの設定
新規プロジェクトを立ち上げたら、アプリの設定を行います。ここで、アプリのアイコンやアプリの表示タイトル(Bundle Display Name)、サポートするデバイスの向き(Device Orientation)を以下のように、設定します。
その前に、今回使用する外部素材ファイルを一気にインポートしてしまいましょう。
今回使用する素材は以下の通りです。
アイコン設定とサポートするデバイスの向きの設定
素材のインポートが完了したら、Project Editorを開き、アイコンをRetina Displayと書かれたエリアの上にドラッグします。
サポートするデバイスの向きとアプリの名前は以下の通り設定します。
Bundle display nameの設定
アプリの表示タイトルを決めている設定項目「Bundle Display Name」を変更します。
Project Editorの「info」タブをクリックして「Bundle Display Name」の項目を次のように変更していきます。
Bundle Display Name |
ドル円換算機 |
画面のデザイン
アプリの設定が完了したら、画面のデザインを行なっていきます。Storyboardを開き、空白のキャンバス上にアイテムを配置していきます。
Autolayoutの無効化
画面レイアウトを3.5インチ(iPhone4S以前)と4インチ(iPhone5以降)に対応させるための設定を行います。
まずはXcode4.5からデフォルトで有効になっているAutolayoutを無効にします。
※Autolayoutはまだ不安定ですので本講座はAutolayoutを無効にして画面デザインを行っていきます。
下記のように①View Controller全体を選択し、②「File Inspector」に変更して、③「Use Autolayout」のチェックを外してください。
背景色の変更
まず、画面の背景色をデフォルトの白から黒へ変更します。ナビゲーターエリアからMainStoryboard.storyboardを選択し、Interface Builderを立ち上げます。一度View上をクリックした後、Attributes Inspectorを開き、Backgroundの色を「Black Color」に変更します。
ラベルの配置
今回のアプリでは、複数のラベルを設置する必要があります。まずは、通貨の単位を示すラベルを設置していきましょう。画面上部に変換前の単位のラベルを、画面下部に変換後の単位のラベルをそれぞれ配置します。これらは、変換のモード(「ドル→円」または「円→ドル」)に応じて、動的に変更されます。
次に、変換後の結果を示すラベルを画面下部に追加します。初期状態では、「0.00」としておきます。
その後、「変換レート:1ドル = 円」変換レートを案内するラベルを貼り付けます。このテキストはアプリ側から特に変更されることのない、静的なテキストとなります。
最後に、1米ドルに対する日本円の金額を表示するラベルを配置します。
このように、アプリのコード側から動的に変更され得るラベルは、静的なテキストと独立した形で配置する必要があります。
テキスト入力フィールドの配置
ラベルの次は、テキスト入力画面を配置します。ライブラリーエリアより、Text Fieldを選択し、画面上部に配置します。
Segmented Controlの配置
最後に、通貨換算の手法(「ドル→円」または「円→ドル」)を選択するためのSegmented Controlという入力オブジェクトを配置します。Text Fieldと同様、ライブラリーエリアからSegmented Controlを選び、画面中央部に配置します。配置後、2つある選択肢のラベルをそれぞれ、「円→ドル」と「ドル→円」に書き換えます。

Segmented Controlは、複数の選択肢の中から1つのオブションをユーザーに選ばせる時に使われます。本講義では2つですが、3つ以上の選択肢(セグメント)必要とする場合、インスペクターからSegmentの個数を指定することが可能です。
異なる画面サイズの対応
3.5インチ及び4インチ画面にて画面のレイアウトが崩れないよう対応していきます。
まず下記画面上部のLabel要素を選択した状態で「Size Inspector」を選択しAutosizingの箇所を上の部分だけ赤色実践になるように変更します。これでLabel要素が上とセンター揃えで固定されました。
次に画面中央のSegmented Controlを選択してAutosizingの赤色実線をすべて削除します。これにより画面中央に固定になります。
最後に画面下部のLabel要素に対してAutosizingを下部分だけ赤色実線を設定します。これで画面下部で固定されます。
これにて、画面のデザインは完了となります。すべての手順をこなした場合、最終的に以下のような画面が出来上がるはずです。
各種変数の宣言
このセクションでは、宣言すべき変数を宣言するとともに、それについての解説を行なっていきます。
前回までと同様、変数の定義はViewController.mの中で行います。状況に応じて、例外はあるのですが、基本的には「クラスのメンバー変数」として、必要な変数を定義していきます。その手法を以下に示します。
@implementation 【クラス名(ViewControllerなど)】
{←中括弧(開く)を忘れずに追加
int XXXX;
【以下、メンバー変数一覧】
}←中括弧(閉じる)を忘れずに追加
|
小数を扱う変数
前回(第2講)でも少し解説しましたが、アプリ上で小数を扱うためには、小数(浮動小数点数)を扱うことのできる変数を準備する必要があります。その浮動小数点数を扱うことのできるは、主にfloat型とdouble型の変数となります。これら2つの違いを以下に示します。
データ型
|
データの種類 |
大きさ |
表現できる値の範囲 |
float |
小数 |
4 Byte |
およそ10-38~1038(有効数字7桁) |
double |
小数 |
8 Byte |
およそ10-308~10308(有効数字15桁) |
float型もdouble型も小数を扱えるという点では共通しているのですが、大きな違いはその大きさにあります。特に断りが無い限り、float型は4バイト(32ビット)であるのに対して、double型は8バイト(64ビット)となります。この違いは表現できる値の範囲に大きく影響します。例えば、float型は小数点以下38桁までしか表現できません。対して、double型は小数点以下308桁まで表現できます。
一般的に考えた場合、この違いはあまりに天文学的でイメージが湧きづらいかもしれませんが、例えば、細かい解析処理や割り切れない計算を行う際、double型の方がより正確に値を把握し、扱えるということになります。一方で、double型の変数はより多くのメモリー領域を専有してしまうという欠点があります。
メモリーの容量が極端に少ない場合は、変数を宣言する上で、必要となるメモリー領域を考慮する必要があるでしょう。一方で、iOSデバイスが持つメモリー容量は一般的なモバイルデバイスの中でも特に大きく、一部の例外を除き、float型やdouble型のレベルではメモリーサイズを気にかける必要はあまりありません。特殊な条件や制約が無い限り、基本的にはdouble型を使用します。
今回、小数を扱えるようにすべきポイントは主に、3つあります。それらを以下に示します。
- 金額の入力値(米ドルでは1ドル未満のセントも扱うため)
- 通貨変換レート(1米ドルに対する日本円の金額)
- 変換後の金額(米ドルでは1ドル未満のセントも扱うため)
これらの要素をコード上でdouble型の変数として扱うものとします。
// 入力金額を扱う変数
double input;
// 換算後の金額を扱う変数
double result;
// 変換レートを扱う変数
double rate;
|
真偽値を扱う変数
Objective-Cでは、bool型の変数を活用することができます。このbool型の変数を用いることで、特定の事象が「真(TRUE)」か「偽(FALSE)」かを保存し、管理することができます。
今回は、ユーザーの意向が「円をドルに変換」することなのか、「ドルを円に変換」することなのかを管理するために、bool型の変数を用います。変数名は「isYenToDollar」とし、「円をドルに変換」する場合は「TRUE」、逆の場合は「FALSE」となるようにします。
UIオブジェクトに関するインスタンス
ドル円換算機では、UILabelをはじめ、様々なUIオブジェクトを活用しています。それらを正しく扱うためにはインスタンスとしてコード上に宣言する必要があります。
まず、UILabelに関しては以下の4つを宣言しておく必要があります。
// 入力値の通貨の単位を表示するラベル(円 or ドル)
IBOutlet UILabel *inputCurrency;
// 換算後の通貨の単位を表示するラベル(円 or ドル)
IBOutlet UILabel *resultCurrency;
// 通貨レートを表示するラベル
IBOutlet UILabel *rateLabel;
// 換算後の金額を表示するラベル
IBOutlet UILabel *resultLabel;
|
次に、今回新たに登場するText FieldやSegmented Controlを管理するためのインスタンスも必要となります。それらを以下に示します。
// 「ドル→円」or「円→ドル」を選ぶためのSegmented Controlのインスタンス
IBOutlet UISegmentedControl *selector;
// 金額を入力するテキストフィールドのインスタンス
IBOutlet UITextField *inputField;
|
- UISegmentedControl型…Segmented Controlを管理
- UITextField型…Text Fieldを管理
ここで、UIオブジェクトを管理するインスタンスは全て、Storyboard上のオブジェクトと関連付ける必要があるため、「IBOutlet」を冒頭に記述する必要があります。
コードにおける変数の宣言
ここまでの解説をもとに、まずは自分でコード上の正しい場所で、変数を宣言してみてください。もしわからない場合は、第2講の説明を見直してください。
編集すべき部分はViewController.mの「@implementation ViewController」の部分です。以下のように、変数の宣言できれば正しいと言えましょう。
@implementation ViewController{
// 入力金額を扱う変数
double input;
// 換算後の金額を扱う変数
double result;
// 変換レートを扱う変数
double rate;
// 「円→ドル」or「ドル→円」の計算方法を記録するためのbool変数
// 「円→ドル」ならば「TRUE」、「ドル→円」ならば「FALSE」
bool isYenToDollar;
// 入力値の通貨の単位を表示するラベル(円 or ドル)
IBOutlet UILabel *inputCurrency;
// 換算後の通貨の単位を表示するラベル(円 or ドル)
IBOutlet UILabel *resultCurrency;
// 通貨レートを表示するラベル
IBOutlet UILabel *rateLabel;
// 「ドル→円」or「円→ドル」を選ぶためのSegmented Controlのインスタンス
IBOutlet UISegmentedControl *selector;
// 金額を入力するテキストフィールドのインスタンス
IBOutlet UITextField *inputField;
// 換算後の金額を表示するラベル
IBOutlet UILabel *resultLabel;
}
|
処理の実装
変数の宣言が完了したあとは、実際の処理を実装していきます。
初期処理
カウンター同様、今回も起動時に初期化すべき変数や、行うべき処理がいくつか存在します。それらのうち、これまでの学習内容で記述できるものを以下に示します。
- 通貨レートを80.5円とする(固定)
- 入力値(input)を「0」とする
- 出力結果(result)を「0」とする
まずは、自分の力で正しいと思われる場所に上記を行うコードを記述してみましょう。わからない場合は第2講のテキストを参照してください。
編集すべきファイルは引き続きViewController.mであり、正しくできた場合は、以下のようになるはずです。
- (void)viewDidLoad {
[super viewDidLoad]; ←必ずこの行の後に記述
// 変換レートを設定(例:1ドルあたり80.5円)
rate = 80.5;
// inputとresultを0に初期化
input = 0;
result = 0;
}
|
次に、今回新しく学ぶ初期化手法について解説します。その前に、その内容を以下に示します。
- UI画面上に変換レート(1ドルあたり80.5円)を表示する
- 初期状態では「円をドルに変換」するものとする
これらをコードとして表現すると、以下のようになります。
// rateLabelの値をrateの値に応じて更新(小数点以下1桁まで)
[rateLabel setText:[NSString stringWithFormat: @"%.1f", rate]];
// 初期状態の計算方法は「円→ドル」に設定
isYenToDollar = TRUE;
|
UILabelにdouble型の値を表示させる時も、int型の時と同様、まずNSStringを用いて、double型の値を文字列に変換した上で、「setText:」メソッドを用いて、画面上のUILabelの表示内容を更新します。double型の値を文字列に変換する際の細かい留意事項は後ほど詳しく説明します。
bool型の変数に値を代入する際は、「TRUE(真)」、または「FALSE(偽)」を代入式の右辺とします。これらを先ほどの「- (void)viewDidLoad」メソッドに追加すると、以下のようになります。
- (void)viewDidLoad {
[super viewDidLoad]; ←必ずこの行の後に記述
【中略】
// rateLabelの値をrateの値に応じて更新(小数点以下1桁まで)
[rateLabel setText:[NSString stringWithFormat: @"%.1f", rate]];
// 初期状態の計算方法は「円→ドル」に設定
isYenToDollar = TRUE;
}
|
やるべき初期化処理は、実はもう1つあるのですが、それは後ほど、テキスト入力に関する解説を行う際に、詳しく説明します。
通貨の変換処理と小数の計算
一通り初期化の実装が完了したところで、通貨の変換処理を行うメソッドの実装をやっていきます。まずは「ViewController.m」に以下のメソッド(処理)を記述します。
// 通貨換算における計算処理
- (void) convert {
// 円→ドル変換の場合
if (isYenToDollar == TRUE) {
// ドルの金額 = 円の入力値を変換レートで割った値
result = input / rate;
// 小数点以下2桁までのみをresultLabelに表示
[resultLabel setText:[NSString stringWithFormat: @"%.2f", result]];
// ドル→円変換の場合
} else if (isYenToDollar == FALSE) {
// 円の金額 = ドルの入力値を変換レートで掛けた値
result = input * rate;
// 小数点以下を切り捨て、整数部分のみをresultLabelに表示
[resultLabel setText:[NSString stringWithFormat: @"%.0f", result]];
}
}
|
bool型の変数を用いた比較
比較や条件分岐に関しては第2講で詳しく解説しましたが、ここではbool型の変数を用いた比較に関する確認を行います。
コードから見て取れるように、bool型の変数に対しても通常の比較演算子を用いることができます。また、比較対象も「TRUE(真)」と「FALSE(偽)」であることがわかります。このようにbool型の変数が持つ真偽値を比較することで、場合分けを行うことができます。
掛け算・割り算と小数の扱い
プログラムの中で、掛け算を行う場合は「*(アスタリスク)」マークを、割り算を行う場合は「/(スラッシュ)」マークを演算子として用います。
// ドルの金額 = 円の入力値を変換レートで割った値
result = input / rate;
// 円の金額 = ドルの入力値を変換レートで掛けた値
result = input * rate;
|
この時、注意する点がいくつかあります。今回はdouble型の変数(小数)同士の計算となります。そのため、正しい結果を得るためには、その結果を受け入れる「result」もdouble型でなくてはいけません。もし仮に、「result」をint型の整数として宣言してしまった場合、小数点以下はすべて切り捨てられてしまうため、思惑通りの結果を得られない場合があります。
なお、「input」か「rate」のどちらか一方が、int型の整数だったとします。この場合も、「result」がdouble型でない場合、小数点以下の値は全て切り捨てられます。
変数を宣言するとき、未然に誤動作を防ぐためにも、求める結果が何なのかを今一度考えた上で、変数の型を決定する必要があります。
割り算における「あまり」
小数を扱わない数同士の割り算の場合、割り切れない場合は「あまり」が発生してしまいます。このあまりは一見プログラミングには関係無いように思えるかもしれません。しかし、その「あまり」を検討すると便利なケースもあります。
例えば、「int型の変数xが2の倍数であるか確かめなさい」という課題が出されたとします。その場合、どうやって確認するのが最も効果的かを考えましょう。
プログラミングを行う場合、2つの数字で割り算を行った場合の「あまり」は「%(パーセント)」マークを演算子として用いることで、求められます。
// 5 ÷ 3 = 1 あまり 2
5 % 3 = 2
// 10 ÷ 4 = 2 あまり 2
10 % 4 = 2
|
「int型の変数xが2の倍数」であるという事象は、「xは2で割り切れる」、すなわち「xを2で割った時のあまりは0」であるという事象と同値です。そこで、以下のif文を用いることで、「変数xが2の倍数」であるか確認できます。
このように、割り算における「あまり」を有効に活用することで、場合分けが行えるケースがあります。このようなテクニックはプログラミングを行う上でよく活用するので、ぜひ覚えてください。
if (x % 2 == 0) {
【xは2の倍数である】
}
|
小数の文字列への変換
第2講では、int型の変数をNSString型の文字列に変換した上で、ラベルに適用しました。ドル円換算機でも、計算結果をUI画面上のラベルに反映させる場合、double型の変数をNSString型の文字列に変換する必要があります。そのコード例を以下に示します。
// 円→ドル変換の場合
[NSString stringWithFormat: @"%.2f", result];
|
基本的には、int型の変数を文字列に変換する場合と大差ありません。唯一違う場所はフォーマット指定子です。第2講でも述べた通り、小数を用いる場合は「%f」というフォーマット指定子を使います。しかし、このフォーマット指定子には留意点があります。
特に断りが無い限り、「%f」単体では小数点以下6桁までを表示してしまいます。従って、上の例で「result = 12.2」であると仮定した場合、この文字列は、「12.200000」として扱われます。
これでは、金額を換算したときに、あまりにわかりづらい計算結果が表示されてしまいます。計算結果における小数点以下の数字に関しては、ドルと円の特性を踏まえ以下のようになっていることが望ましいと言えます。
- ドル…小数点以下2桁
- 円…小数点以下0桁(整数部のみを表示)
そこで、役に立つのが、フォーマット指定子における表示桁数の指定です。上記例を見ると、フォーマット指定子が「%.2f」となっています。これは、「小数点以下2桁までを表示」ということを明示しています。同様に「%.4f」となっている場合は小数点以下4桁までが表示され、「%.0f」となっている場合は整数部のみが表示されます。
この機能を用いることで、「円からドルに変換」する場合と「ドルから円に変換」する場合で、表示形式を切り分けことが可能となります。その例を、以下に示します。
// 円→ドル変換の場合(小数点以下2桁まで表示)
[resultLabel setText:[NSString stringWithFormat: @"%.2f", result]];
// ドル→円変換の場合(整数部のみ表示)
[resultLabel setText:[NSString stringWithFormat: @"%.0f", result]];
|
変換手法の切り替え処理
次に、変換手法の切り替えを行うメソッド(処理)を実装していきます。今回は、変換手法の切り替えを行うにあたって、UISegmentedControlを用いました。UISegmentedControlでは、選択肢のボックスが左から「0」、「1」、「2」、という順でint型の識別番号が割り当てられます。以下の例では、「First」という選択肢が選択されています。この場合、「First」に該当する「0」という識別番号がint型の値として「selectedSegmentIndex」というプロパティー要素に代入されます。選択内容がユーザーによって変更される度に、「selectedSegmentIndex」に代入される値は変更されます。
選択内容に応じて処理を切り分ける場合、まず、該当するSegmented Controlと紐付くIBAction型のメソッドを作成する必要があります。正しく関連付けが行われた場合、ユーザーによって選択内容が変更される度にIBAction型のメソッドが呼ばれるので、そのメソッドの中で、「selectedSegmentIndex」の値を参照し、場合分けを行います。メソッドの例を以下に示します。
// Segmented Controlの選択が変更された時の処理
- (IBAction)【メソッド名】:(id)sender {
// selectedSegmentIndexの値に応じて切り分け
if(selector.selectedSegmentIndex == 0) {
【Firstが選択された場合処理】
} else if (selector.selectedSegmentIndex == 1) {
【Secondが選択された場合処理】
} else if (selector.selectedSegmentIndex == 2) {
【Thirdが選択された場合処理】
}
}
|
このIBAction型のひな形に応じて、通貨の変換モード(「ドル→円」または「円→ドル」)が変わった際の処理をViewController.mに記述します。メソッド名は「changeCalcMethod」とし、具体的には、以下の設定が必要となります。
- isYenToDollarの真偽値の切り替え(「円→ドル」の場合は「真」)
- inputCurrencyラベルを書き換え(「円→ドル」の場合は「円」)
- resultCurrencyラベルを書き換え(「円→ドル」の場合は「ドル」)
最後に、変換モードが変わった際、入力値に応じて計算を行い、正しい変換結果を表示する必要があります。それを実現するためには、先程の工程で実装した「- (void) convert」というメソッドを呼び出します。その例を以下に示します。なお、ここにある「self」とは、「同じクラス内のメソッド」を明示しています。
すべての必要な機能を実装した場合、コードは以下のようなものとなります。
ViewController.m
- (IBAction)changeCalcMethod:(id)sender {
// 左側(円→ドル)が選択された場合(selectorの値が「0」のとき)
if(selector.selectedSegmentIndex == 0) {
isYenToDollar = TRUE;
[inputCurrency setText:@"円"];
[resultCurrency setText:@"ドル"];
// 右側(ドル→円)が選択された場合(selectorの値が「1」のとき)
} else if (selector.selectedSegmentIndex == 1) {
isYenToDollar = FALSE;
[inputCurrency setText:@"ドル"];
[resultCurrency setText:@"円"];
}
// 通貨を変換
[self convert];
}
|
キーボード入力の取り扱い
ドル円換算機では、キーボード入力よって変換する金額を入力します。そのためのText FieldをInterface Builderを用いてUI画面上に配置したかと思いますが、それを正しく扱うためにはコーディングも必要となります。コーディングを何もせず、UI画面上にText Fieldの配置のみを行った場合、Text をタッチすると、画面下部からキーボードが出現し、テキスト入力を行えるようになります。

しかし、このままでは入力された文字列を、コード側で受け取ったり、参照したりすることができません。その上、このままでは何をやってもキーボードは収納されず、「return」キーを押しても何もおきません。そこで、キーボード入力の正しい扱い方をここでは解説します。
UITextFieldについて
Text Fieldを管理するUITextFieldクラスは、テキストの入力操作は勿論、キーボードの管理や入力文字列の記録や操作等も包括的に扱っています。これにより、テキスト入力に関係する煩雑な手続きが簡略化されています。一方で、開発者の求める様々な要求に柔軟に対応させるために、一部処理を手動で実装しなくては行けません。デフォルト状態では「return」キーの反応が無かったり、キーボードを収納させたりすることができないのは、そのためです。
一部の処理を手動で実装する前に、Delegate通知に関する記述をコード上で行わなくてはなりません。Delegate通知とは、異なるクラス間でイベントの発生等を通知するということです。この場合は、UITextField上発生したイベントをView Controllerに通知する必要があります。
これらを踏まえ、文字入力操作を行う時の動作手順を以下に示します。少し複雑ですが、「理屈よりも手順から」ということを心がけて、学習しましょう。
- UITextFieldDelegateプロトコルをView Controllerに設定
- UITextFieldのDelegateをView Controllerに設定(Delegate通知)
- 「return」キーによってキーボードを収納し、通貨変換の処理を行う
- 入力された文字列をdouble型のデータに変換した上で、「input」に代入
プロトコルの設定について
前述した通り、まずはView Controllerに対して、UITextFieldDelegateクラスのプロトコルを設定する必要があります。まずは何も考えず、ViewController.hを以下のように改変してください。
ViewController.h
【変更前】
@interface ViewController : UIViewController
↓
【変更後】
@interface ViewController : UIViewController <UITextFieldDelegate>
|
UITextFieldDelegateは、UITextFieldと他のクラス(今回の場合はView Controller)の橋渡し役を果たしています。UITextFieldDelegateプロトコルを設定することによって、UITextFieldからのDelegate通知があった場合の処理(メソッド)をView Controllerの中で定義し、実装することが許可されます。
Delegate通知の設定
プロトコルの設定を行ったら、実際のDelegate通知の受け渡し先を設定します。今回は、UITextFieldである「inputField」が発するDelegate通知をView Controller側で受け取る必要があります。そこで、View Controllerが最初に起動した時に呼ばれる、「- (void)viewDidLoad」メソッド内に以下を追記します。
ViewController.m
// 画面起動時に呼ばれる処理
- (void)viewDidLoad {
[super viewDidLoad];
【中略】
// inputFieldのDelegate通知をViewControllerで受け取る
inputField.delegate = self;
}
|
「return」キーが押された場合の処理
最後に、「return」キーが押された時に呼ばれる処理(メソッド)をView Controllerの中に実装します。「return」キーが押された場合、まずは入力された値を「input」という変数に代入し、キーボードを閉じた上で、実際の通貨換算を行う必要があります。
「return」キーが押されると、UITextFieldから受け手のクラス(今回はView Controller)に対して、Delegate通知がなされます。その際、受け手のクラス内の、「-(BOOL)textFieldShouldReturn」というようにメソッドが呼び出されます。このメソッドは自動的に生成されるものではなく、プロトコルの設定とDelegate通知の設定を行った後で、ViewController.mに手動で実装しなくてはいけません。以下に、実際のコードを記述します。
ViewController.m
// UITextFieldのキーボード上の「Return」ボタンが押された時に呼ばれる処理
- (BOOL)textFieldShouldReturn:(UITextField *)sender {
// 受け取った入力値(NSString型の文字列)をdoubleに変換し、inputに代入
input = [sender.text doubleValue];
// キーボードを閉じる
[sender resignFirstResponder];
//通貨を変換
[self convert];
return TRUE;
}
|
「-(BOOL)textFieldShouldReturn」が呼び出された際、引数(ひきすう)として、Text Fieldが渡されます。この引数に関しては第4講で詳しく述べますが、今は「メソッドに渡される素材」として考えてください。場合によっては、同じ画面上に複数のText Viewを配置することもあるでしょう。一方、それぞれで「return」キーが押されても、その時に発せられるDelegate通知は同一のものです。
そこで、「どのText Viewで『return』キーが押されたか」を判断するために、引数として該当するText Fieldが渡されます。このメソッドでは、そのText Fieldを「sender」という変数名を用いて参照することができます。例えば、「inputText」で「return」キーが押された場合、「sender」は「inputText」を指し示すことになります。
文字列からdouble型への変換
基本的にText Fieldに入力されたテキストはNSString型の文字列として取り扱われます。テキストこれまでは、int型やdouble型の変数をNSString型に変換する手法は取り上げましたが、計算を正しく行うためには、ユーザーによって入力された金額(NSString型)をdouble型に変換する必要があります。基本的には、NSStringクラスの「-(double)doubleValue」メソッドを使うことで、容易に変換を行うことができます。その例を以下に示します。
// 受け取った入力値(NSString型の文字列)をdoubleに変換し、inputに代入
input = [sender.text doubleValue];
|
UI画面とコードの関連付け
ここまでで、基本的にコードの記述は全て完了となります。そこで、これまでに設置したUI画面上の部品とコード上の処理を関連付けます。
ラベルの関連付け
今回は動的に変更されるラベル(換算の結果や通貨の単位など)が全部で4つあります。それらを順番にコード上のUILabelオブジェクトと関連付けます。
まずは、入力金額の通貨の単位を示すラベルから関連付けます。これまでと同様、ラベルを右クリックし、View Controller上にドラッグし、「inputCurrentcy」と結びつけます。
次に、換算結果の通貨の単位を示すラベルを、同様にView Controller上の「resultCurrentcy」と結びつけます。
現在の変換レートを示すラベルは「rateLabel」と関連付けます。
最後に、換算結果の金額を示すラベルを「resultLabel」と関連付けます。
Text Fieldの関連付け
ラベルの次は、金額を入力するText Fieldの関連付けを行います。ラベルと同様に、View Controller上の「inputField」と関連付けます。
Segmented Controlの関連付け
最後にSegmented Controlの関連付けを行います。Segmented Controlの場合、2つの要素を関連付ける必要があります。1つ目は、UISegmentedControlクラスのインスタンスそのものです。これは、選択内容を参照するのに必要となります。2つ目は、選択肢が変更された時に呼び出されるIBAction型のメソッドです。
まず、Segmented ControlのReference Outletとして、View Controllerの「selector」を選びます。次に、イベント一覧にある、「Value Changed」イベントをView Controller上の「changeCalcMethod」と関連付けます。
ビルドとデバッグ、動作試験
これにて、すべての作業は完了となります。編集内容を全て保存し、ビルドを行なってください。このテキストの内容をすべて正しくやった場合、特に問題なくアプリが動作するはずです。しかし、人間は様々な「ミス」を犯してしまうため、その「ミス」に起因するエラーや誤動作が引き起こされる場合があります。ここでは、そのミスを発見し、取り除く作業(デバッグ)に関する解説と、「ドル円換算機」の動作試験を行います。
エラーとデバッグ
人間が犯してしまうミスで、よくあるのが、タイプミスです。ViewController.mを例に考えてみましょう。まず、以下のコードを見てください。
// 通貨換算における計算処理
- (void) convert {
// 円→ドル変換の場合
if (isYenToDollar == TRUE) {
// ドルの金額 = 円の入力値を変換レートで割った値
result = input / rate
// 小数点以下2桁までのみをresultLabelに表示
[resultLabel setText:
[NSString stringWithFormat: @"%.2f", result]];
// ドル→円変換の場合
} else if (isYenToDollar = FALSE) {
// 円の金額 = ドルの入力値を変換レートで掛けた値
result = input * rate;
// 小数点以下を切り捨て、整数部分のみをresultLabelに表示
[resultLabel setText:[NSString stringWithFormat: @"%.0f", result];
}
}
|
このコードには3つの誤りがあります。それ故、このコードを含むアプリをビルドしようとしても、エラーが発生してしまい、ビルドが一切許されないという状況に陥ってしまいます。
まずは、自分でどこにミスがあるか、じっくり考えてみてください。ここでミスを発見できれば、かなり洞察力があると言えるでしょう。しかし、プログラミングを始めたばかりの場合、慣れるまでは少し時間がかかるでしょう。幸い、Xcodeはビルド時に遭遇したエラー箇所を的確に表示してくれる機能をもっています。その例を以下に示します。
このように、Xcodeはビルド時のエラーを引き起こしている行を的確にマークしてくれます。それらを頼りに、誤りの内容を探ってみましょう。
セミコロン(;)の付け忘れ
1つ目のエラーは、「Expected ‘;’ after expression」というものです。
エラー内容が示す通り、この誤りは行末にセミコロン(;)が無いことに起因しています。 Objective-Cにおいて式の代入やメソッドの呼び出し、変数等の定義を行う場合は、必ず行末にセミコロンを記述剃る必要があります。
例外があるとすれば、行末に「()」・「{}」・「[]」等の括弧を含む行といえるでしょう。詳しくは今まで書いたコードを見返して、セミコロンの必要なところ、必要で無いところを見てみてください。
無効な比較演算子の利用
2つ目の問題箇所は、黄色で記されています。このように黄色で示された問題箇所は「ワーニング(警告)」と呼ばれ、「とりあえずビルドは許すけど、動作過程で不具合を起こす可能性が高い」ということを示しています。
その内容を見てみると、「Using the result of an assignment as a condition without parenthesis」とあります。端的に解釈すると、「if文の中で比較演算子ではなく、代入演算子がつかわれているけど、大丈夫?」という内容です。
括弧の過不足
3つ目の問題箇所は、「括弧の過不足」に由来するエラーです。
このような括弧の過不足は、典型なミスの一種です。コードを記述する際は、「開いた括弧は必ず閉じる」ということは必ず肝に命じて下さい。
ビルド中にエラーやワーニングが出てしまったら、その内容に従って、コード中の問題箇所を適宜デバッグ(修正)しましょう。
動作試験
エラーやワーニングを解消できたら、実際にビルドして実行しましょう。金額を入力し、変換レートに応じて、正しく金額を換算できたら、動作試験成功となります。
まとめ
第3講では、少数や真偽値の扱い方を学習しました。また、少数を用いた掛け算や掛け算、テキストの入力やSegmented Control等の使い方もカバーしました。最後にコード上のエラーの対処法やデバッグの概念も学びました。
今回扱った内容も、プログラミングを上達させる上での基礎となるものばかりです。毎回新しい内容ばかりで、体系的に概念を理解するのは大変かもしれませんが、引き続き復習と自己アレンジを積極的に行なって、「覚える」よりも「慣れる」ことに重点をおいて、学習を進めましょう。