【iOS】iOSアプリ開発入門~ SwiftとUIの接続編３~

前回はボタンタップイベントを受けラベルの色を変更する方法について投稿しました。
SwiftとUIの接続編２：https://qiita.com/euJcIKfcqwnzDui/items/93f010b989a4d333f0b9

今回はいくつか簡単な処理を紹介します。
Swiftのコーディング練習がてらこのあたりの処理を入れてもう少しアプリらしくしてみましょう。

処理をいれる前にこちらに目を通しておくと理解しやすいかもしれません。
【付録】Swift基礎(変数・型)：https://qiita.com/euJcIKfcqwnzDui/items/5d4c674a975c90a3db3f

それではいつも通りプロジェクトを開いて実装していきましょう。

## カウントアップさせる処理
ボタンをタップする毎に表示される数字が増えるような処理を紹介します。
### デバッグコンソールにカウントアップを表示する
まずカウントアップさせるには今いくつまでカウントされているかという状態を保持しておく必要があります。
この状態を保持するためのスペースをプロパティに準備しておきます。
以下のようにコードを編集します。

```swift:ViewController.swift
class ViewController: UIViewController {
    var count: Int = 0  // < 追加
    @IBOutlet weak var label: UILabel!
    
    @IBAction func tapButton(_ sender: Any) {
        self.label.text = "Hello World"
        self.label.backgroundColor = UIColor.red
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}
```

`count`というプロパティを`Int`型で定義しました。
`Int`は整数型と呼ばれるものです。数字、特に整数で扱うものはInt型で定義します。

一部例外はありますがプログラムでは型を意識する必要があります。
整数ならInt型、少数ならDouble型、文字列ならString型というようにそれぞれ用途に合わせて型を指定してあげなければいけません。
今回の場合はボタンをタップする毎に数字を１ずつ増やすという処理をしたいのでInt型として定義しました。

`var count: Int = 0`というように定義していますが、この`= 0`いうのは初期化処理です。
つまりcountの初期値は0という値ですよとしてあげています。

それではこのcountを使って実装していきます。

`tapButton`の処理を以下のように書換えてみます。
書換えたら実行してボタンを何度かタップしてみてください。

```swift:ViewController.swift
    @IBAction func tapButton(_ sender: Any) {
        print("加算前：\(self.count)")
        self.count = self.count + 1
        print("加算後：\(self.count)")
        print("-----")
    }
```

デバッグコンソールに以下のように出力されました。
print()関数に関しては[以前](https://qiita.com/euJcIKfcqwnzDui/items/f794ee8b996e6d650027#%E5%86%85%E5%AE%B9%E3%81%AE%E8%A7%A3%E8%AA%AC)しました。デバッグコンソールに出力するための処理です。

```
加算前：0
加算後：1
-----
加算前：1
加算後：2
-----
加算前：2
加算後：3
-----
```

見ればなんとなくわかるかもしれませんが、ボタンをタップする度に`self.count = self.count + 1`という処理で`count`の値に1を加算しています。

ここで出てきた=や+は**演算子**または**オペレータ**と呼ばれます。
プログラミングではこの演算子を使い計算をしていきます。
※演算子の詳細は[こちら](https://qiita.com/euJcIKfcqwnzDui/items/f9a8f52429d15cb0c1a2)にまとめているので目を一度目を通してもらえればと思います。

「+」はそのままの意味で足し算を行います。
少し注意が必要なのは「=」で、こちらは**代入演算子**と呼ばれています。
数学上の意味では「=」は等価、つまり左辺と右辺の関係式を表しますがプログラム上では代入を意味します。
少しニュアンスが難しいかも知れませんがここの処理は`self.count + 1`の計算結果を`self.count`に代入しています。その結果`self.count`の値が１加算されたものに書き換わります。
(ちなみに等価の演算子は「==」です)

一回目のタップでは代入される前の`self.count`の初期値は０のため`print("加算前：\(self.count)")`では「０」が表示され、加算後`self.count`の値は１に書き換わったため`print("加算後：\(self.count)")`では「１」が表示されています。

二回目のタップでは`self.count`の値は一回目に１に書換えているため`print("加算前：\(self.count)")`では「１」が表示され、さらに書き換えを行い２に更新しています。

試しに代入を行わず以下のような処理にしてみましょう。

```swift:ViewController.swift
    @IBAction func tapButton(_ sender: Any) {
        print("加算前：\(self.count)")
        print("加算後：\(self.count + 1)")
        print("-----")
    }
```
以下のように出力されました。

```
加算前：0
加算後：1
-----
加算前：0
加算後：1
-----
加算前：0
加算後：1
-----
```
これは`self.count`に代入を行っていないため初期値の０のままになっているためです。
`self.count + 1`の計算は`print("加算後：\(self.count + 1)")`で１と表示されているので正しく行われていますが、`self.count`が更新されないため同じ結果が常に表示されています。
値を更新したい場合は必ず代入するようにしてください。

このようにして値を更新、保持しながらアプリの状態を制御していきます。

### カウントアップ結果をラベルに表示する
print()関数だけではアプリの表示は変更されないので`self.count`を表示してみましょう。
これまでの内容を理解できていれば特に難しいことはなく、[ラベルの表示変更](https://qiita.com/euJcIKfcqwnzDui/items/93f010b989a4d333f0b9#%E8%A1%A8%E7%A4%BA%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)とカウントアップの処理を組み合わせるだけです。

コードを以下の様に書き換え実行してみましょう。

```swift:ViewController.swift
    @IBAction func tapButton(_ sender: Any) {
        self.count = self.count + 1
        self.label.text = "カウント：\(self.count)"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.label.text = "カウント：\(self.count)"
    }
```
ラベルの表示が「カウント：０」から始まり、ボタンをタップする毎にカウントが増えていきました。
基本的には前項の処理とは変わらず`self.count = self.count + 1`で１ずつ加算していき、その値をラベルに表示しているだけです。

処理をもう少し詳しく見ててみましょう。

まず`tapButton`内の処理について。
先程と同様に`self.count = self.count + 1`で`self.count`が更新されていますね。
更新した結果を`self.label.text = "カウント：\(self.count)"`に代入しています。
そのためラベルには加算された値が表示されています。
ラベルの更新の際`self.count`が`\()`で囲まれています。
冒頭で言いましたが**プログラムでは型を意識する**必要があります。
UILabelのtextの定義を見てみます。(見方は[前回](https://qiita.com/euJcIKfcqwnzDui/items/93f010b989a4d333f0b9#%E8%A1%A8%E7%A4%BA%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)説明しました)

`open var text: String?`というように定義されています。
「?」はひとまず気にせず、`String`型つまり文字列型で定義されており、`count`は`Int`型なので型が異なるということがわかります。
プログラムでは型が異なる場合は直接代入できないという決まりがあります。
そこで`Int`を`String`に変換してあげる必要があります。
型を変換する処理のことを**キャスト**と呼び、`\()`は`Int`を`String`にキャストするための処理です。
キャストしてあげた結果`"カウント：\(self.count)"`は`String`型に変換され`text`に代入できるようになりました。

次は`viewDidLoad`の処理について。
`tapButton`の処理では更新した値を表示していますが、１を加算した値を表示しているため初期値の０が表示されることはありません。
そもそも`tapButton`はボタンをタップするというイベントを起こして初めて動く処理のため、画面を表示した瞬間のラベルの表示を制御できません。
ですがアプリを実行したときは「カウント：０」と表示されていました。
これを実現するための処理が`viewDidLoad`の内容です。
この`viewDidLoad`はプロジェクトを作成した段階ですでに定義されていましたが、何をするための処理なんでしょう？
今回は詳しく説明しませんがアプリの画面、つまりViewControllerには**ライフサイクル**というものがあり、「画面が表示された」、「画面が非表示」になったなど、画面の表示状態などによって勝手に呼ばれるメソッドが元々定義されています。
`viewDidLoad`もライフサイクルの１つで「画面がメモリ上に確保された」タイミングで呼ばれます。
基本的にこのタイミングで画面の初期化処理を行います。
初期化処理として`self.label.text = "カウント：\(self.count)"`を行ったため画面が表示された瞬間「カウント：０」と表示されていたというわけです。

## カウント毎にテキストの色を変える
もう少し遊んでみましょう。
先程等価式は「==」の演算子を使うと少し話しましたがこの等価演算子を使ってみます。

プログラムには条件判定を行うためにif文を呼ばれるものが用意されています。EXCELなどにもありますがそれと同じです。
「if文」を使えば特定の条件の場合のみ行う処理を記述することができます。
(if文については[こちら](https://qiita.com/euJcIKfcqwnzDui/items/21117d9192317c2fa37b)で紹介しています)

コードを以下の様に書き換え実行してみましょう。

```swift:ViewController.swift
    @IBAction func tapButton(_ sender: Any) {
        self.count = self.count + 1
        self.label.text = "カウント：\(self.count)"
        
        let remainder: Int = self.count % 2
        if remainder == 0 {
            self.label.textColor = UIColor.red
        } else {
            self.label.textColor = UIColor.blue
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.label.textColor = UIColor.red
        self.label.text = "カウント：\(self.count)"
    }
```

タップする度に文字色が赤→青→...と変わります。

`viewDidLoad`で文字色の初期値を赤に指定していますね。
`tapButton`に注目してください。
`let remainder = self.count % 2`とあります。
まず「%」は余りを求める演算子です。`self.count % 2`は`self.count`を２で割った余りを結果として返します。
つまり偶数の場合は０、奇数の場合は１となり、`remainder`には０ ro １が代入されます。

`remainder == 0`ではremainderと０が等価かどうかを計算しています。
このように「==」など左右の値の関係を比較する演算子を**比較演算子**と呼びます。
比較演算子は他に「>」,「>=」,「<」,「<=」があります。これらの意味は数学と同じで大なり、大なりイコールといった意味になります。
比較演算子の計算結果は`Int`型ではなく`Bool`型となります。`Bool`型は論理型と呼ばれ真偽値、つまりtrue/falseを格納します。
今回の場合０と比較しているので`remainder`が０ならtrue、１ならfalseの値が返されます。
試しに`print(remainder == 0)`とするとtrue or falseが表示されます。

「if文」では真偽値を判定します。
構文としては以下の様になります。

```swift
if 真偽値 {
    trueの場合の処理
} else {
    falseの場合の処理
}
```
従って`count`が偶数の場合は文字色が赤となり、奇数の場合は文字色が青となったというわけです。

余談ですがif文は以下のような感じでelseなしやさらにif文で繋げることもできます。

```swift
// else なし
if self.count % 2 == 0 {
    // countが「2n」の場合の処理
}

// if文を繋げる
if self.count % 3 == 0 {
    // countが「3n」の場合の処理
} else if self.count % 3 == 1 {
    // countが「3n+1」の場合の処理
} else {
    // 上記判定に当てはまらなかった場合の処理
}
```

## 最後に
今回はカウントアップや条件分岐など少しプログラミング的な処理を入れてUIを更新してみました。
もちろんこれは簡単な例でさらに複雑な処理を与えてあげればもっと細かい制御ができるようになります。

今回紹介した内容は簡単ではありますが全てのプログラミングに共通する考え方で非常に重要な内容です。
もし理解できなかった場合は読み直しさらに練習するなどで自分のものにしてください。

特にif文は非常に重要で、他に繰り返しを制御するfor文というものがありますが
if文とfor文があれば全ての処理を記述できると言われています。
しっかりと理解できるようにしましょう。

次回はアプリの画面遷移について説明していきます。
画面遷移編１：https://qiita.com/euJcIKfcqwnzDui/items/679b1cd30694519f4916

本連載ではプログラミング未経験からiOSアプリ開発が行えるようになることを目的としています。
今までの投稿をまとめていますのでこちらもご覧ください。
http://naoyalog.com/