カウンターアプリ

講義の目標

  • 変数(整数・文字列)やメモリー管理の概念の理解すること
  • 変数への値の代入や、簡単な計算(足し算・引き算)を理解すること
  • 複数条件を含む条件分岐や比較構文を理解すること
  • UILabelやUIButtonに代表されるUIオブジェクトの概念を理解すること

はじめに

今回の課題アプリは「カウンター」となります。イベント会場等で人数を数えたりする際に使われる道具をiOS上で再現したものであり、ボタン操作によって画面上の数字が増減する実にシンプルなアプリです。

完成品のサンプルは以下よりダウンロードできます。イメージが湧かない方は是非ご確認ください。

iOS完成品サンプル(カウンターアプリ)

それでは、早速開発を始めて行きましょう!

プロジェクトの立ち上げと設定

新しいアプリを作る際は、まず、新規プロジェクトを立ち上げとアプリの設定を行います。

新規プロジェクトの立ち上げ

Welcom to Xcode画面から、Create a new Xcode projectを選択します。そしてSingle View Appを選択します。

今回は以下のように設定します。

入力項目 入力値
Product Name Counter
Team None
Oganization Name 任意(”ALJ”など自分が所属している組織の名前を入れる)
Oganization Identifier jp.co.al-j (ユニークなID)
Language Swift
User Interface Storyboard
Use Core Data チェックを外す
include Unit Tests チェックを外す
include UI Tests チェックを外す

アプリの設定

新規プロジェクトを立ち上げたら、アプリの設定を行います。

対応ディバイスの設定とサポートするデバイスの向き設定

プロジェクトを選択し、対応ディバイスの設定を行います。
対応ディバイスをiPhoneのみとし、デバイスの傾きは「Portrait」にします。

Bundle Nameの設定

アプリの表示タイトルを決めている設定項目「Bundle Name」を変更します。
Project Editorの「info」タブをクリックして「Bundle Name」の項目を次のように変更していきます。

入力項目 入力値
Bundle Name カウンター

外部素材のインポート

今回使用する外部素材ファイルを一気にインポートしてしまいましょう。

素材ダウンロード

今回使用する素材は以下の通りです。

ファイル名 説明
iPhone-Notification-20@2x.png Notification用x2画像
iPhone-Notification-20@3x.png Notification用x3画像
iphone-icon-60@2x.png アイコンx2画像
iphone-icon-60@3x.png アイコンx3画像
iphone-setting-29@2x.png 設定x2画像
iphone-setting-29@3x.png 設定x3画像
iphone-spotlight-40@2x.png Spotlight用x2画像
iphone-spotlight-40@3x.png Spotlight用x3画像
iphone-icon-1024@1x.png アイコン画像
btn_minus.png マイナスボタンx1画像
btn_minus@2x.png マイナスボタンx2画像
btn_minus@3x.png マイナスボタンx3画像
btn_plus.png プラスボタンx1画像
btn_plus@2x.png プラスボタンx2画像
btn_plus@3x.png プラスボタンx3画像
btn_reset.png リセットボタンx1画像
btn_reset@2x.png リセットボタンx2画像
btn_reset@3x.png リセットボタンx3画像

アイコン設定

画像素材のiconフォルダの中のアイコン画像をプロジェクトに取り込んでください。

アイコン以外の画像取り込み

アイコン画面以外は以下の方法で画像を取り込みます。

ドラッグ後以下のように表示されていることを確認してください。

スプラッシュ画面設定

次にスプラッシュ画面を作成します。

今回は以下のようにアイコンと同じデザインを作成していきたいと思います。

「LaunchScreen.storyboard」を選択し、Viewの背景色を設定します。

Viewプロパティの背景色(background)は以下にします。

Labelオブジェクトを配置し、以下のように設定します。

メイン画面のデザイン

ナビゲーションエリアからMain.storyboardを選択します。

ラベルの配置

次に、カウントする際の計上値を表示するためのUILabelを用意します。ライブラリーエリアからLabelを選択し、画面上に配置します。

配置したラベルを一度クリックした後、Attributes Inspectorを開き、フォントや文字色等のを下記に設定します。

このようにUIオブジェクト(部品)の見た目や大きさなどを動的にコードから変更するためには、コード上で宣言する当該部品(UILabel、UIButtonなど)のインスタンスと部品そのものを紐付けする必要があります。その手法は後ほど詳しく解説します。

ボタンの配置

ラベルの次は、カウント数を増減させたり、初期値である「0」に戻したりするためのボタンを準備します。ライブラリーエリアからButtonを選び、3つのボタンを以下のように配置します。

このままでも、アプリの動作としては問題ないですが、やはり見た目が悪いですよね。そこで、配置したButtonを独自の画像に置き換えます。ボタンを一度クリックした上で下図のとおりAttributes Inspectorを表示させ、①、②、③の設定を以下にしてで画像を変更してください。

プルダウンが開いたら、「Custom」を選択します。今後、任意の画像をボタンとして用いる際は、ボタンの「Type」として「Custom」を選ぶことになります。次に、ボタンに用いる画像を選びます。ボタン用の画像は「Image」と書かれたブルダウンの中から、該当するものを選択します。なお、ここで表示されるのは、あらかじめインポートした外部素材となっています。

他のボタンも同じ要領で下図のとおりに背景を画像にしてください。

Auto Layoutによる異なる画面サイズの対応

レイアウトの設定をします。

リセットボタンの調整

まず初めにリセットボタンの調整をします。下図のように Auto Lyoutを設定してください。

Pinについて

今ラベルに設定したのはPinメニューと呼ばれるものでView要素自身の幅・高さ、他のView要素との距離などの制約を追加することができます。

設定箇所 設定内容
隣接するView要素との距離に関する制約
・設定したい方向の赤い点線を選択する
・設定したい距離を入力する
・数値右側の▼で隣接しなていないViewも選択可能
選択中のView要素自身の幅・高さに関する制約
Width・・・横幅
Height・・・縦幅
複数選択中のView要素の幅・高さを等しくする制約
Equal Width・・・複数選択しているView要素の横幅を等しくする
Equal Height・・・複数選択しているView要素の縦幅を等しくする
Aspect Ratio・・・選択しているView要素の縦・横のサイズの割合を維持
設定した制約を満たすためにViewのframeを更新するかどうかを設定

リセットボタンにおいては今回の設定で親のViewからの下・左右の距離を固定にし、縦横サイズを今の割合で維持するように設定した事になります。

Issuesメニュー

設定中の制約に不整合がある場合に正しい制約を追加したり、制約をまとめて消すなど行うことができます。上5つのメニューは選択中のView要素のみに対して、下5つはViewController内のすべてのView要素に対しての制約の操作を行います。

設定項目 設定内容
Update Frames 設定中の制約を満たすようにViewのFrameを変更します
Update Constraints 設定中の制約を満たすように制約の値を変更します
Add Missing Constraints 制約が足りていない場合、自動的に制約を追加します
Reset to Suggested Coustraints 設定中の制約を全て消して、自動的に新たな制約を設定します
Clear Constraints 設定中の制約をすべて消します

Auto Layoutの修正

リセットボタンの下の余白が少し少ないのでAuto Layoutの設定を修正します。
下図の①〜②のとおりに、Size Inspectorを表示させ、リセットボタンを選択した状態でButtom Space toの箇所のEditをクリックします。

Constantの箇所を25にします。

このように一度設定した内容はSize Inspectorで変更する事ができます。
下記のように余白が変更されました。

プラス・マイナスボタンの調整

次にプラスとマイナスのボタンの調整をします。
まずはプラスボタンです。先ほどのリセットボタンを同じようにPinメニューを開いて下図の①〜④のとおりに変更します。

次に、リセットボタンとプラスボタンを選択した状態で①〜④の操作をしてください。

次に下図のとおりUpdate Frameをする事によりリセットボタンのAuto Layoutの設定が確定します。

Align設定について

今プラスボタンとリセットボタンを選択して行った設定はAlign(揃え)の設定です。
Alignメニューでは、他のView要素との揃えに関する制約を追加することができます。基本的にAlignメニューからは、複数View要素を選択してから制約を追加します。

設定箇所 設定内容
複数選択中のView要素を各辺で揃える制約
英語や日本語のように左から右に書く言語ではLeading=Left、Trailing=Right
アラビア語のように右から左に書く言語ではLeading=Right、Trailing=Left
複数選択中のView要素を水平、垂直方向に中心を揃える制約。
BaselinesはUILabel等の場合に、文字のBaselineを揃える制約
選択中のView要素を包括するSuperViewの中心に揃える制約
設定した制約を満たすためにViewのframeを更新するかどうかを設定

今回の設定ではリセットボタンとプラスボタンの右側(Leaging)の位置を揃える設定をしました。

2つのViewのサイズの割合の制約をつける

今回のアプリではリセットボタンとプラスボタン、マイナスボタンの横幅の比率を100:45:45にします。

まず、プラスボタンを選択した状態で下図のとおり、controlキーを押しながらドラッグしリセットボタンにドロップしてください。

Equal Witdhを選択してください。これでリセットボタンとプラスボタンの横幅が同じ大きさになりました。

それから比率を45:100にします。プラスボタンを選択した状態でSize Inspectorを表示させ、Equal Width to Buttonの箇所のEditボタンをクリックします。

Multipilerの箇所を45:100にします。

次に下図のとおりUpdate Frameをする事によりリセットボタンのAuto Layoutの設定が確定します。

これでプラスボタンのAuto Layoutの設定は完了です。

プラスボタンを同じ要領でマイナスボタンもAuto Layoutを設定しましょう。

これで3つのボタンのAuto Layoutの設定は完了です。プレビューで確認して様々なiPhone端末で綺麗にボタンが配置されていると思います。

ラベルのAuto Layoutの設定

最後にラベルのAuto Layoutを設定します。
まず、ラベルを選択してAlignメニューを出し、Horizontal ...にチェックを入れます。
これで画面に対して常にラベルが水平方向に中央で配置されるようになります。

次にPinメニューを出し、下図のとおりに設定します。
上下左右(画面の上端からプラス、マイナスボタンまでと、画面の左右)の間隔の設定を行っています。

これで今回のアプリのデザインは完了です。

UIオブジェクトをコードと結びつける

今、Main.storyboardでデザインしたオブジェクト(ボタンやラベル)とコードをアシスタントエディタで接続していきます。

下図の部分においてPreviewからAutomatic -> Viewcontroller.swiftに変更します。

ラベルのIBOutlet接続

次に、左側のstoryboardのラベルをcontrolキーを押しながらドラッグして下図の箇所にドロップします。

class Viewcontroller...override func viewDidLoad...の間にドラッグ・ドロップしてください。

ドロップしたら、下記の吹き出しが表示されますのでNameの箇所にcountLabelを入力してください。

このように自動的にViewcontroller.swiftにプログラムが追加されます。
これでstoryboardで配置したラベルとViewcontroller.swiftで定義したcountLabelの変数が関連付けられた事になります。

ボタンのIBAction接続

次にボタンタップ時のアクションをViewController.swiftに定義します。
先ほどと同様にプラスボタンを選択してcontrolキーを押しながらドラッグし下図の場所にドロップしてください。

override func didReceiveMemoryWarning...の上の箇所にドロップしてください。

下図の①〜③の手順で設定してください。

下記のようにIBActionが追加されます。

同様の手順でマイナスボタン、リセットボタンのIBAction設定をしてください。

※ マイナスボタンのNameはminusPushed、リセットボタンのNameはresetPushedにしてください。

ViewController.swiftファイルは下記のようになりました。

ViewController.swift

class ViewController: UIViewController {

@IBOutlet weak var countLabel: UILabel!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

// プラスボタンが押された時
@IBAction func plusPushed(sender: AnyObject) {

}

// マイナスボタンが押された時
@IBAction func minusPushed(sender: AnyObject) {

}

//リセットボタンが押された時
@IBAction func resetPushed(sender: AnyObject) {

}


}

変数と単純な条件分岐

このセクションでは、変数や条件分岐等についての解説を行うとともに、実際の処理の実装を行ないます。

変数

まずは、実際にコードの記述から行なっていきます。My Very First Appの時と同様、今回改変するコードのファイルも1つだけです。ナビゲーターエリアから、「ViewController.swift」を選択し、以下のように書き換えます。

ViewController.swift

class ViewController: UIViewController {
@IBOutlet weak var countLabel: UILabel!
// ▼▼ 追加 ▼▼
// 合計値を管理する「変数」
var count = Int()
// ラベル用の文字列を管理する「インスタンス」
var countLabelText = String()
// ▲▲ 追加 ▲▲

変数とデータ型

変数とは、いわば、データを一時的に蓄えておくための「箱」のようなものです。プログラム上でやり取りされる様々データは、このような変数に格納されることによって、様々な処理が行われるようになります。

プログラムが実行される際は、ソースコードに記述されたとおりに、コンピュータのメモリー上にデータを格納するための変数が確保されます。その後、CPUはメモリー上に確保された変数から様々なデータを読みだし、処理や演算を施した上で、その結果を再び変数に保存します。コンピュータを購入する際、メモリーの容量(例:4GB)を参考にする方も多いかと思いますが、データを一時的に保存する変数を確保することが、メモリーの大きな役目となっています。

通常、みかんを入れるためにはみかん箱が、牛乳をいれるためには牛乳瓶がそれぞれあるように、変数も格納するデータに応じて様々な形や大きさがあります。例えば、整数を格納するためには「Int」型の変数(箱)を用います。このような変数の型はデータ型と呼ばれ、種類に応じて大きさも異なります。プログラムを記述する上で、頻繁に使用するデータ型とその大きさと以下に示します。

データ型 データの種類 大きさ 表現できる値の範囲
Int 整数 4Byte -2147483648〜2147483648
Float 小数 4Byte およそ10-38~1038(有効数字7桁)
Double 小数 8Byte およそ10-308~10308(有効数字15桁)

ここで、変数の宣言の仕方を見ていきたいと思います。コード上の以下の部分に注目してみてください。ここで宣言されている「count」という変数は、整数を格納するための「Int型」の変数であるこということがわかります。

// 合計値を管理する「変数」
var count = Int()

インスタンスとは

次にインスタンスについて解説します。インスタンスとは、オブジェクトクラスに根ざした変数のようなものです。オブジェクト思考、及びクラスやインスタンスに関する詳細は次回解説しますが、現段階では少し特殊で「高機能なデータ型の変数」として認識しておいてください。

このコードで扱われているインスタンスの種類(データの型)には以下の3つがあります。

Stringクラス型 文字列を扱うデータ型
UILabelクラス型 UI画面上のラベルを管理するデータ型
UIButtonクラス型 UI画面上のボタンを管理するデータ型

C言語では、文字を扱うためのデータ型としてchar型の変数が用意されています。しかし、iOSが用いるSwiftはより簡単、かつ便利に文字列を扱うことのできるStringというクラスを装備しています。今後、iOSプログラミングを進めていく上で、文字列を扱う場合、特に断りの無い限り、このStringを用いることとします。

また、今回のコードでは、UILabelやUIButtonを宣言する際、先頭に「IBOutlet」と記述されていていることが見て取れます。この「IBOutlet」は、該当するインスタンスが「Interface Builder上のオブジェクトである」ということ明示するものです。UILabelやUIButtonで管理するボタンやラベルがStoryboard等に配置したオブジェクトである場合、必ずこの「IBOutlet」を先頭に記述する必要があります。

変数の宣言とメモリーの管理

変数をプログラム内で使用するためには、その変数を使うことを事前に「宣言」する必要があります。この宣言という作業を行うことで、その変数を保存するためのメモリー領域が確保されます。一方で、宣言後に手動でメモリーを確保する必要がある場合もあります。

特定の変数を宣言した後、手動でメモリーを確保する必要がある場合があると述べましたが、確保されたメモリーをしっかり管理する必要があります。なぜなら、メモリーはデバイス全体で共有するものであり、専有することができないからです。実世界で「共有物を借りて使い終わったら、しっかり返す」という理屈があるかと思いますが、メモリーにも同じことが言えます。メモリーでも「借りたら返す」を徹底しない場合、アプリが異常終了するなどの現象が引き起こされます。

幸い、iOS 5 SDKから、メモリー管理を格段に手軽にする手法が取り入れられました。それは「Automatic Reference Counting(以下ARC)」という機能です。詳しい原理は省きますが、ARCはアプリとは独立した、メモリーの管理人のようなものです。その管理人が、常にそれぞれのアプリの挙動を見張りつつ、メモリー管理を代行しているものとして認識してください。

変数への値の代入と起動時の初期処理

変数を定義した後は、その変数を用いた処理を実装していきます。まずは、起動時に行われる処理から実装していきます。ViewController.swiftのコード上にある、「viewDidLoad」と書かれている部分を以下のようにコードを追加してください。

ViewController.swift

//画面起動時に呼ばれる処理
override func viewDidLoad() {
super.viewDidLoad()
//////////////// ▼▼ 追加 ▼▼ ////////////////
// 画面起動時にcountを0に初期化
count = 0
//////////////// ▲▲ 追加 ▲▲ ////////////////
}

この「override func viewDidLoad()」というメソッド(処理)は、この画面が最初に立ち上がった時に最初に呼び出されます。今回の例では、カウント数を管理する「count」という変数に「0」を代入します。変数に値を代入する際は通常の数式と同様に、「=」(イコール)を使います。

加算処理と文字列の取り扱い

初期化が完了したら、カウント数の増減を掌る処理を実装します。まずは、以下に示す「増やす」処理をViewController.swift上の「@IBAction func plusPushed(sender: AnyObject)」に記述してください。基本的に新しいメソッド(処理)を追加する際には、「class」の中に記述します。

// プラスボタンが押された時
@IBAction func plusPushed(sender: AnyObject) {
//////////////// ▼▼ 追加 ▼▼ ////////////////
// countに1を加算
count = count + 1
// ラベル用に文字列を用意
countLabelText = "\(count)"
// countLabelの値を更新
countLabel.text = countLabelText
//////////////// ▲▲ 追加 ▲▲ ////////////////
}

上のコードは「増やす」ボタンが押された時に行われるIBAction型のメソッド(処理)をplusPushedという名前で定義しています。IBAction型のメソッドとは、UIButtonが押された時の処理であるという明示したメソッドとなっています。
変数を用いた計算を行う場合、左辺に代入先の変数、右辺に計算内容を記述します。今回はボタンが1回押される毎に「1」が「count」に加算されるので、以下のようになります。

// countに1を加算
count = count + 1

カウント数を管理する「count」に「1」を加算し終わったら、次は画面の表示を更新する必要があります。差し当たり、まずは整数を文字列に変換する必要があります。その際は「”(変数)”」で文字列に変換できます。最初のステップで宣言した様々な変数の中に、「countLabelText」という文字列を格納するためのインスタンスもあったかと思います。その中に「count」の値を文字列として格納します。

// ラベル用に文字列を用意
countLabelText = "\(count)"

最後に、「countLabel」というUI画面上のラベルの表示を更新します。

// countLabelの値を更新
countLabel.text = countLabelText

ここまで、カウント数を「増やす」処理は完了となります。

減算処理と条件分岐

「増やす」ことができるようになったら、次は、「減らす」ことを考えなくては行けません。やり方としては、「増やす」処理とほぼ同一ですが、大きく異なる部分が2つあります。

1つ目の違いは「増やす」かわりに「減らす」計算が必要なことです。増やす時は「count + 1」をしましたが、減らす場合は「count - 1」となります。

// countから1を減算
count = count - 1

2つ目は、負の数に対する扱いです。今回のカウンターでは、0未満の数は計上しないものとします。そこで、減算を行う前に、処理前の値が正の数であることを確認する必要があります。
処理に対して、条件を指定するためには、if文というものを使用します。if文の構文を以下に示します。

if 【条件文】 {
    【処理内容】
}

ここにある「条件文」は、特定の処理内容が起こりうる条件を示したものです。今回は、「count」が正の数である場合のみ、減算を行うことなので、条件文は「count > 0」というようになります。なお条件文の中では、比較演算子というものを使用できます。このような比較演算子を用いることで、変数の値に応じた処理の場合分けを行うことが可能です。その例を以下に示します。

比較演算子 使用例 「真」となる条件
== count == 0 「count」は「0」と一致
!= count != 0 「count」は「0」と不一致
< count < 0 「count」小なり「0」
<= count <= 0 「count」は「0」以下
> count > 0 「count」大なり「0」
>= count >= 0 「count」は「0」以上

これらを用いて、「減らす」処理を実装してみてください。骨格は、「増やす」処理とほぼ同一です。「減らす」処理は「minusPushed」と呼ぶことにします。先ほど記述した「plusPushed」メソッドを参考に自分で考えて、記述してみてください。どうしてもわからない場合は次のページの解説をみてください。

以下に「減らす」ボタンが押された時の「minusPushed」メソッド(処理)を示します。記述するファイルは引き続き、ViewController.swiftです

ViewController.swift

// マイナスボタンが押された時
@IBAction func minusPushed(sender: AnyObject) {
//////////////// ▼▼ 追加 ▼▼ ////////////////
// もし、countが整数であれば...
if count > 0 {
// countから1を減算
count = count - 1
}
// ラベル用に文字列を用意
countLabelText = "\(count)"
// countLabelの値を更新
countLabel.text = countLabelText
//////////////// ▲▲ 追加 ▲▲ ////////////////
}

加算処理と減算処理の特殊な表記

変数を用いた加算処理や減算処理を行う場合、式の左辺に代入先の変数を、右辺に計算内容を記します。一方で、今回のように特定のInt型の変数に対して「1」を増やしたり、減らしたりする場合、簡略化した特殊な表記を行うことも出来ます。その例を以下に示します。

// countに「1」を増やす
count++
// countから「1」を減らす
count--

丁寧に代入式を記述することも、もちろん大切ですが、このような単純な計算の簡易表記手法は非常に便利かつ、よく使うことになるので、覚えるようにしてください。

ユーザーによる値の初期化

これまでの処理で、ボタン操作によってカウント数を1つずつ増やしたり、減らしたりすることができるようになりました。一方で、ユーザーはカウント数の値を「0」にリセットする機能も望むはずです。そこで、「リセット」ボタンが押された時に押されるメソッド(処理)実装していきます。以下のコードを、ViewController.swift上に記述してください。

ViewController.swift

@IBAction func resetPushed(sender: AnyObject) {
//////////////// ▼▼ 追加 ▼▼ ////////////////
// countを0に初期化
count = 0
// ラベル用に文字列を用意し、ラベルを更新
countLabelText = "\(count)"
countLabel.text = countLabelText
//////////////// ▲▲ 追加 ▲▲ ////////////////
}

このメソッド(処理)は「@IBAction func plusPushed(sender: AnyObject)」や「@IBAction func minusPushed(sender: AnyObject)」と同様、ボタンが押された時の処理を示すIBAction型のメソッドです。ボタンが押されると、「count」に「0」が代入され、ラベルの数字も「0」になります。

これで、実装が完了となります。

ビルドと動作試験

ここまでの手順で、カウンターとして最低限必要な機能は揃いました。すべてのファイルを保存した上でアプリをビルドし、動作の検証を行いましょう。

まず、正常にビルドが完了し、アプリが起動することを確認しましょう。また、ボタン操作によって、カウント数が増えたり、減ったり、リセットできることも確認しましょう。

高度な条件分岐

これまでの内容で、1つの条件のみによる単純な条件分岐は扱ってきました。一方で、実際にはより複雑な条件によって、処理を切り分ける必要が出てきます。このセクションでは、多段階の場合分けや複数の条件を含む条件分岐に関して議論します。

多段階の条件分岐

条件分岐に用いるif文は、else文と組み合わせることで、多段階の比較処理を行い、複数通りの場合分けを行えます。以下にその例を示します。

if 【条件文1】 {
    【条件文1が「正」の時の処理内容】
} else if 【条件文2】 {
    【条件文1が「偽」、かつ条件文2が「正」の時の処理内容】
} else {
    【条件文1、条件文2、共に「偽」の時の処理内容】
}

上の例では、3段階の比較処理を行うことで、3通りの場合分けを行なっていることがわかります。比較処理の段階には、特に制限はなく、状況に応じて、より細かく場合を分けて処理を行うことも可能です。

複数条件を含む条件分岐

さらにif文では、論理演算子を用いることによって、1つ条件文に複数の条件を指定することができます。以下にその例を示します。

if 【条件文1】 && 【条件文2】 {
    【条件文1、かつ、条件文2、が共に「正」の時の処理内容】
}

この例における「&&」は「かつ」を意味する論理演算子です。「&&」以外に、よく使う論理演算子を以下に示します。

論理演算子 使用例 「真」となる条件
&& count > 0 && count < 11 「count」は「0」より大きく、かつ、「11」より小さい
|| count < 0 || count > 11 「count」は「0」より小さい、または、「11」より大きい

高度な条件分岐を用いたカウンターの改良

それでは、多段階の場合分けや複数の条件を含む条件分岐を用いることで、カウンターの機能を工夫してみましょう。現状では、カウント数に応じてラベルの値のみが更新される設計となっていまが、それに一工夫を加えて、カウント数に応じて、ラベルの色を変える処理を追加します。

ラベルの文字色の変更

ラベルの色をコードから動的に変える際は、ラベルを掌る「countLabel」というインスタンスのメンバー変数の1つである、「textColor」に「UIColor」で表現された色データを代入することで実現できます。

クラスやメンバー変数の詳細は次回解説しますが、現段階では、以下のようにコードを記述すればラベルの文字色が変えられると覚えてください。

// ラベルを「緑色」に変更
countLabel.textColor = UIColor.green

UIColorには、緑以外にも、以下のような色が予め定義されています。

UIColor.black
UIColor.blue
UIColor.brown
UIColor.clear 透明
UIColor.cyan シアン
UIColor.darkGray 濃い灰
UIColor.gray
UIColor.green
UIColor.lightGray 薄い灰
UIColor.magenta マゼンタ
UIColor.orange オレンジ
UIColor.purple パープル
UIColor.red
UIColor.white
UIColor.yellow

ここに使用したい色がない場合、UIColorクラスを用いて、自分の好きな色を合成することも可能です。

場合分けに応じた文字色の変更

それでは、このUILabelのtextColorというメンバー変数と、条件分岐を組み合わせ、以下のようにラベルの文字色を変更できるように改良してみましょう。なお、解答例は後述しますが、まずはそれを見ずに実装してください。

  • カウント数が「0以上10未満」->「白色」
  • カウント数が「10以上20未満」->「緑色」
  • カウント数が「20以上30未満」->「黄色」
  • カウント数が「30以上」->「赤色」

答えを見ることなく、指定通りの動作をさせることに成功した方は条件分岐の概念を大方理解していると言えるでしょう。

それでは、実際の解答例を見ていきます。まずは、「増やす」ボタンが押されたときに呼ばれる「@IBAction func plusPushed(sender: AnyObject)」というメソッドの中で、「count」を増加させ後、「count」の値に応じて場合分けを行い、色を変更させる処理を記述します。なお、以下に示す手法は数多くある実装方法の一例であり、唯一絶対の解答例ではありません。

ViewController.swift

@IBAction func plusPushed(sender: AnyObject) {
【中略】※countを増加
//////////////// ▼▼ 追加 ▼▼ ////////////////
// countの大小に応じて、ラベルの色を変更
if count >= 0 && count < 10 {
countLabel.textColor = UIColor.black
} else if count >= 10 && count < 20 {
countLabel.textColor = UIColor.green
} else if count >= 20 && count < 30 {
countLabel.textColor = UIColor.yellow
} else {
countLabel.textColor = UIColor.red
}
//////////////// ▲▲ 追加 ▲▲ ////////////////
}

この例では、2つの条件を含む条件文を用いて「count」の範囲を指定するとともに、else文を用いて4通りの場合分けを行なっています。

次に、「減らす」ボタンが押されたときに呼ばれる「@IBAction func minusPushed(sender: AnyObject)」というメソッドの中でも、「count」を減少させ後に、「count」の値に応じて場合分けを行い、色を変更させる処理を記述します。以下の例では、計算処理を行った後に「count」の値を比較して、ラベルの色を変更しているため、場合分けを行う部分は「@IBAction func plusPushed(sender: AnyObject)」と同一です。

ViewController.swift

@IBAction func minusPushed(sender: AnyObject) {
【中略】※countを減少
//////////////// ▼▼ 追加 ▼▼ ////////////////
// countの大小に応じて、ラベルの色を変更
if count >= 0 && count < 10 {
countLabel.textColor = UIColor.black
} else if count >= 10 && count < 20 {
countLabel.textColor = UIColor.green
} else if count >= 20 && count < 30 {
countLabel.textColor = UIColor.yellow
} else {
countLabel.textColor = UIColor.red
}
//////////////// ▲▲ 追加 ▲▲ ////////////////
}

ここまでで、カウント数を増減する毎に値に応じて色が変化するという処理の実装が完了しました。しかし、本当の完成まではもう1ステップの処理が必要となります。それは、「リセットボタンを押した時に、文字色を白に戻す」という処理を実装することです。その例を以下に示します。

ViewController.swift

//リセットボタンが押された時
@IBAction func resetPushed(sender: AnyObject) {
【中略】※countを「0」にリセット
//////////////// ▼▼ 追加 ▼▼ ////////////////
//ラベルの色を白に戻す
countLabel.textColor = UIColor.white
//////////////// ▲▲ 追加 ▲▲ ////////////////
}

お疲れ様でした。これですべての処理の実装が完了となります。もう一度ビルドとアプリの実行を行い、正常にラベルの文字色が変更されることを確認してください。以下にアプリの実行例を示します。