前回はボタンタップイベントを受けラベルの色を変更する方法について投稿しました。
SwiftとUIの接続編2:https://qiita.com/euJcIKfcqwnzDui/items/93f010b989a4d333f0b9
今回はいくつか簡単な処理を紹介します。
Swiftのコーディング練習がてらこのあたりの処理を入れてもう少しアプリらしくしてみましょう。
処理をいれる前にこちらに目を通しておくと理解しやすいかもしれません。
【付録】Swift基礎(変数・型):https://qiita.com/euJcIKfcqwnzDui/items/5d4c674a975c90a3db3f
それではいつも通りプロジェクトを開いて実装していきましょう。
カウントアップさせる処理
ボタンをタップする毎に表示される数字が増えるような処理を紹介します。
デバッグコンソールにカウントアップを表示する
まずカウントアップさせるには今いくつまでカウントされているかという状態を保持しておく必要があります。
この状態を保持するためのスペースをプロパティに準備しておきます。
以下のようにコードを編集します。
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型というようにそれぞれ用途に合わせて型を指定してあげなければいけません。
今回の場合はボタンをタップする毎に数字を1ずつ増やすという処理をしたいのでInt型として定義しました。
var count: Int = 0
というように定義していますが、この= 0
いうのは初期化処理です。
つまりcountの初期値は0という値ですよとしてあげています。
それではこのcountを使って実装していきます。
tapButton
の処理を以下のように書換えてみます。
書換えたら実行してボタンを何度かタップしてみてください。
@IBAction func tapButton(_ sender: Any) {
print("加算前:\(self.count)")
self.count = self.count + 1
print("加算後:\(self.count)")
print("-----")
}
デバッグコンソールに以下のように出力されました。
print()関数に関しては以前しました。デバッグコンソールに出力するための処理です。
加算前:0
加算後:1
-----
加算前:1
加算後:2
-----
加算前:2
加算後:3
-----
見ればなんとなくわかるかもしれませんが、ボタンをタップする度にself.count = self.count + 1
という処理でcount
の値に1を加算しています。
ここで出てきた=や+は演算子またはオペレータと呼ばれます。
プログラミングではこの演算子を使い計算をしていきます。
※演算子の詳細はこちらにまとめているので目を一度目を通してもらえればと思います。
「+」はそのままの意味で足し算を行います。
少し注意が必要なのは「=」で、こちらは代入演算子と呼ばれています。
数学上の意味では「=」は等価、つまり左辺と右辺の関係式を表しますがプログラム上では代入を意味します。
少しニュアンスが難しいかも知れませんがここの処理はself.count + 1
の計算結果をself.count
に代入しています。その結果self.count
の値が1加算されたものに書き換わります。
(ちなみに等価の演算子は「==」です)
一回目のタップでは代入される前のself.count
の初期値は0のためprint("加算前:\(self.count)")
では「0」が表示され、加算後self.count
の値は1に書き換わったためprint("加算後:\(self.count)")
では「1」が表示されています。
二回目のタップではself.count
の値は一回目に1に書換えているためprint("加算前:\(self.count)")
では「1」が表示され、さらに書き換えを行い2に更新しています。
試しに代入を行わず以下のような処理にしてみましょう。
@IBAction func tapButton(_ sender: Any) {
print("加算前:\(self.count)")
print("加算後:\(self.count + 1)")
print("-----")
}
以下のように出力されました。
加算前:0
加算後:1
-----
加算前:0
加算後:1
-----
加算前:0
加算後:1
-----
これはself.count
に代入を行っていないため初期値の0のままになっているためです。
self.count + 1
の計算はprint("加算後:\(self.count + 1)")
で1と表示されているので正しく行われていますが、self.count
が更新されないため同じ結果が常に表示されています。
値を更新したい場合は必ず代入するようにしてください。
このようにして値を更新、保持しながらアプリの状態を制御していきます。
カウントアップ結果をラベルに表示する
print()関数だけではアプリの表示は変更されないのでself.count
を表示してみましょう。
これまでの内容を理解できていれば特に難しいことはなく、ラベルの表示変更とカウントアップの処理を組み合わせるだけです。
コードを以下の様に書き換え実行してみましょう。
@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)"
}
ラベルの表示が「カウント:0」から始まり、ボタンをタップする毎にカウントが増えていきました。
基本的には前項の処理とは変わらずself.count = self.count + 1
で1ずつ加算していき、その値をラベルに表示しているだけです。
処理をもう少し詳しく見ててみましょう。
まずtapButton
内の処理について。
先程と同様にself.count = self.count + 1
でself.count
が更新されていますね。
更新した結果をself.label.text = "カウント:\(self.count)"
に代入しています。
そのためラベルには加算された値が表示されています。
ラベルの更新の際self.count
が\()
で囲まれています。
冒頭で言いましたがプログラムでは型を意識する必要があります。
UILabelのtextの定義を見てみます。(見方は前回説明しました)
open var text: String?
というように定義されています。
「?」はひとまず気にせず、String
型つまり文字列型で定義されており、count
はInt
型なので型が異なるということがわかります。
プログラムでは型が異なる場合は直接代入できないという決まりがあります。
そこでInt
をString
に変換してあげる必要があります。
型を変換する処理のことをキャストと呼び、\()
はInt
をString
にキャストするための処理です。
キャストしてあげた結果"カウント:\(self.count)"
はString
型に変換されtext
に代入できるようになりました。
次はviewDidLoad
の処理について。
tapButton
の処理では更新した値を表示していますが、1を加算した値を表示しているため初期値の0が表示されることはありません。
そもそもtapButton
はボタンをタップするというイベントを起こして初めて動く処理のため、画面を表示した瞬間のラベルの表示を制御できません。
ですがアプリを実行したときは「カウント:0」と表示されていました。
これを実現するための処理がviewDidLoad
の内容です。
このviewDidLoad
はプロジェクトを作成した段階ですでに定義されていましたが、何をするための処理なんでしょう?
今回は詳しく説明しませんがアプリの画面、つまりViewControllerにはライフサイクルというものがあり、「画面が表示された」、「画面が非表示」になったなど、画面の表示状態などによって勝手に呼ばれるメソッドが元々定義されています。
viewDidLoad
もライフサイクルの1つで「画面がメモリ上に確保された」タイミングで呼ばれます。
基本的にこのタイミングで画面の初期化処理を行います。
初期化処理としてself.label.text = "カウント:\(self.count)"
を行ったため画面が表示された瞬間「カウント:0」と表示されていたというわけです。
カウント毎にテキストの色を変える
もう少し遊んでみましょう。
先程等価式は「==」の演算子を使うと少し話しましたがこの等価演算子を使ってみます。
プログラムには条件判定を行うためにif文を呼ばれるものが用意されています。EXCELなどにもありますがそれと同じです。
「if文」を使えば特定の条件の場合のみ行う処理を記述することができます。
(if文についてはこちらで紹介しています)
コードを以下の様に書き換え実行してみましょう。
@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
を2で割った余りを結果として返します。
つまり偶数の場合は0、奇数の場合は1となり、remainder
には0 ro 1が代入されます。
remainder == 0
ではremainderと0が等価かどうかを計算しています。
このように「==」など左右の値の関係を比較する演算子を比較演算子と呼びます。
比較演算子は他に「>」,「>=」,「<」,「<=」があります。これらの意味は数学と同じで大なり、大なりイコールといった意味になります。
比較演算子の計算結果はInt
型ではなくBool
型となります。Bool
型は論理型と呼ばれ真偽値、つまりtrue/falseを格納します。
今回の場合0と比較しているのでremainder
が0ならtrue、1ならfalseの値が返されます。
試しにprint(remainder == 0)
とするとtrue or falseが表示されます。
「if文」では真偽値を判定します。
構文としては以下の様になります。
if 真偽値 {
trueの場合の処理
} else {
falseの場合の処理
}
従ってcount
が偶数の場合は文字色が赤となり、奇数の場合は文字色が青となったというわけです。
余談ですがif文は以下のような感じでelseなしやさらにif文で繋げることもできます。
// 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文があれば全ての処理を記述できると言われています。
しっかりと理解できるようにしましょう。
次回はアプリの画面遷移について説明していきます。
画面遷移編1:https://qiita.com/euJcIKfcqwnzDui/items/679b1cd30694519f4916
本連載ではプログラミング未経験からiOSアプリ開発が行えるようになることを目的としています。
今までの投稿をまとめていますのでこちらもご覧ください。
http://naoyalog.com/