小学生でも天気予報アプリが作れるようになるSwift開発マニュアル記事 超基礎編その2

こんにちは!ケロッピです。
好きなカエルは雨蛙です。
この記事はSwiftでiOSアプリを作るにあたっての備忘録を書いていくシリーズの第二弾となっています。
前回の記事では、開発環境を用意してボタンやラベルを置いて起動するまでを解説しました。
是非とも前回の記事もご覧いただけると幸いです。
1.ボタンを押した時の動きを追加しよう
さて、前回まではアプリ開発と称しつつ、プログラミングらしいことは一切行なって来ませんでした。
読者諸兄はそろそろコードを書きたくて手指が震えてきた頃合いだと思われますので、配置したボタンを押した時の動作を書いていきましょう。

まずは左のメニューから「ViewController.swift」をクリックして表示してください。
ここにコードを追加していくことで、先ほどシミュレーターに表示した静止画に等しい画面に対し、魂を吹き込むことになります。

次に、赤丸をつけた箇所をクリックして、「ViewController.swift」と「Main.storyboard」を並べて表示します。

並べて表示したら、controlキーを押したまま天気予報のラベルを、「ViewController.swift」の画面へドラッグ&ドロップします。

するとUI部品と、コードを紐付けるためのメニューが表示されます。
「Name」の欄に「titleLabel」と名前を入れて、「Connect」をクリックすることで紐づけられます。
これで「titleLabel」の内容や見た目をコードで変更できるようになりました。
なお、このメニューのパラメータはそれぞれ以下のような意味合いがあります。
ConnectionUI部品とプロパティを接続する方法を指定するパラメータです。ラベルのようなUI部品そのものを接続する場合は「Outlet」を選択します。ObjectUI部品が実装されるオブジェクトが表示されます。Nameコード内でアクセスするために、接続するプロパティ名を指定します。
任意の名前をつけることができますが、変数名として使用されるため、コードの可読性を考慮してわかりやすい名前をつけることが推奨されています。Type接続するプロパティのタイプを指定します。
今回のようにラベルをそのまま接続する場合は「UILabel」を選択します。Storagestrongまたはweakを設定することで、メモリ管理に関する設定を行うものです。
strongを設定した場合、参照が保持されるため、必要なくなった時には明示的にnilを代入しないと循環参照を起こしてメモリリーク(使用していないメモリを開放することなく保持し続けること)が起きることがあります。
weakにすることで上記の現象を回避できるといった違いがあるため、今回はweakにしています。
次にボタンを押した時の動作を追加します。
ラベルと同じように、controlキーを押したままボタンを、「ViewController.swift」の画面へドラッグ&ドロップします。

今回はボタンを押した時の動作を紐づけるので、「Connection」を「Action」に変更します。
「Name」の欄に「touchUpButton」と名前を入れて、「Connect」をクリックすることで紐づけられます。
なお「Action」に変更した場合、メニューのパラメータはそれぞれ以下のような意味合いがあります。
ConnectionUI部品とプロパティを接続する方法を指定するパラメータです。UI部品に操作が行われた時の動作を設定したい場合は「Action」を選択します。Object動作が実装されるオブジェクトを選択するところです。
デフォルトで実装しようとしているViewControllerが選択されます。Name動作の名前を設定します。
メソッド名に相当し、コードの可読性を考慮しないといけない点は「Outlet」を選択した場合と同じです。Type動作の戻り値の型を選択します。Event動作が発生する条件を選択します。
ボタンがタップされた時やボタンを押した指が離れた時など、用途に合わせて設定します。Arguments動作に渡される引数を設定します。
通常は、senderを選択し、動作が発生したオブジェクトを引数として渡します。
senderは自動的に追加されるため、基本的には何も設定する必要はありません。
さて、ここまでの操作でボタンをタップして指を離した瞬間に、以下の{}の中に書いたことが実行されるようになりました。
@IBAction func touchUpButton(_ sender: Any) {
}
この{}の中に以下の一文を入れてみましょう。
// Labelのテキストを変更
titleLabel.text = "ボタンが押された!"
この状態で「Product」→「Run」とクリックして、シミュレーターを起動してみましょう。

ボタンを押すと、「天気予報」の文字が「ボタンが押された!」に変われば成功です。
2.二つ目の画面を作る
ボタンを押してラベルが変わるだけだと味気ないので、もう少しよくあるものを作ってみます。
ここまでは一つの画面で完結していましたが、世の中に出回っているアプリは複数の画面を持ちます。
今回のアプリも二つ目の画面を作り、ボタンを押すとその画面へ遷移するようにしてみましょう。
なお、今回はStoryboardを複数作成し、それぞれ一つのStoryboardに一つの画面を作る方法について書いています。
この方法を選ぶ理由は、複数人で一つのアプリを開発する場合に、お互いの修正がコンフリクトするのを避けやすくなるからです。
仮に一つのStoryboard上に全ての画面があった場合、一つのファイルを複数人が修正することになります。
そして複数人が同時に違った修正を行うことで、互いの修正内容が衝突しやすくなります。
これを回避するために、複数人がそれぞれ担当する画面ごとにStoryboardを分ける、ということです。
逆に言えば、Swift勉強し始めで一人で作業している場合には、「画面が増えすぎて管理しにくくなってきた」などを解消するメリットしかないですが……「こういうこともできるよ」ということでこの方法にしています。
まずは二つ目の画面を作ります。

「File」→「New」→「File」とクリックしていくとファイル作成のメニューが表示されます。
「Storyboard」を選択して「Next」をクリックし、次の画面でファイル名と保存場所を指定したら「Create」を押します。
ファイル名は「SecondVIewController」とします。

これで「SecondVIewController.storyboard」が作成されました。
二つ目の画面とわかるように、ラベルを配置します。

さらに青い箇所をクリックして、

このViewのinspectorを表示し、「is Initial VIewController」にチェックを入れます。
チェックを入れることで、そのStoryboard上で最初に表示されるViewControllerを指定することができます。
この指定がないと、他のStoryboardから遷移してきた際などにエラーの原因となることがあります。

このViewのinspectorを表示し、「is Initial VIewController」にチェックを入れます。
チェックを入れることで、そのStoryboard上で最初に表示されるViewControllerを指定することができます。
この指定がないと、他のStoryboardから遷移してきた際などにエラーの原因となることがあります。

次に「Main.storyboard」に戻ってからラベルやボタンを配置した時と同じように、オブジェクトの一覧を表示して「Storyboard Reference」を配置します。
これは他のStoryboardを参照するためのものです。
Storyboard Referenceを使用することで、Storyboardをより小さな単位に分割し、それぞれ別々のStoryboard上でアプリの画面を開発することができます。
そうすることで複数の開発者で同時に作業する場合でも、前述の通りアプリケーションの統合の際にコンフリクトを回避しやすいというメリットがあります。

配置した「Storyboard Reference」をクリックして、inspectorの「Storyboard」のところを「SecondVIewController」と設定します。
これで「Main.storyboard」上から「SecondVIewController」を参照できるようにしました。

次に赤丸で囲った箇所をクリックして、controlキーを押したまま、先ほど配置した「Storyboard Reference」へドラッグ&ドロップし、「Show」をクリックします。
なお、ドラッグ&ドロップした際に表示されるメニューは、画面遷移時の動きを指定するためのものです。
「Show」を選択すると、遷移元から遷移先のViewへ横からスライドするように画面が動くようになります。

するとこのように、「Storyboard Reference」へ向かって矢印がつきます。

矢印をクリックしてinspectorを表示し、「Identifier」に「toSecond」と入力します。
これは参照する時のコードを書くために使います。

次に「Editor」→「Embed In」→「Navigation Controller」をクリックして、NavigationControllerを追加します。
NavigationControllerは、複数のViewControllerを階層的に管理し、画面間を簡単に往来することができるようにしてくれるものです。
ここまで準備ができたら「ViewController.swift」をクリックして表示してください。
touchUpButtonの{}の中に以下を追加します。
// 画面遷移を行う
self.performSegue(withIdentifier: "toSecond", sender: nil)
この状態で「Product」→「Run」とクリックして、シミュレーターを起動してみましょう。

ボタンを押して、二つ目の画面に遷移できれば成功です。
また変数名やファイル名などの命名について少しだけ。
こういった命名は後々のメンテナンスしやすさのために、誰が見てもわかる名前を心がけましょう。
そう言葉にするのは簡単ですが、実際はクラスや変数の用途などによってどうすれば後々困らないかは、結構頭を悩ませます。
今回は説明のために二つ目の画面のStoryboardを「SecondVIewController.storyboard」と命名していますが、実際にアプリを作る際は用途がすぐわかる名称を設定してください。
3.コードの見た目を綺麗にする
中身も大事ですが外観も劣らず大事という話をしましたが、中身を綺麗にする方法の一つをご紹介します。

例えばこの画像のように、不思議なインデント(字下げ)がされている場合、「command + A」で全て選択し、「control + I」を入力します。

これで不思議なインデントが修正されます。
比較的簡単な操作ですぐ行えるので、忘れずに整える癖をつけましょう。
これはショートカットキーでインデントなどを修正してくれる機能ですが、コードの見た目を綺麗にするというのは本来これだけに留まりません。
「リーダブルコード」などで調べてみてください。
どのように書くのが良いか、さまざまな改善方法が出てきます。
ただしコード規約やプロジェクトでの決まり事、エンジニアの考え方等によって正解が変わってくるところもあると思います。
前述した命名方法も含め、畢竟、個人のスタイルの違いへと繋がっていく内容なのでここでは詳細を割愛します。
4.次回に続く
いかがでしたでしょうか。
今回は超基礎編その2ということで、とりあえず動かして画面遷移するものの作成を一気に駆け抜けました。
疑問に思った箇所などは是非とも調べて、理解を深めてみてください。
この後も、シリーズは続いていきます。
今回の記事が少しでもアプリ開発の一助になれば幸いです。