テーブルと画面切替-note

iOSアプリを作ろう・テーブルビューと画面切り替え

実用的なアプリに欠かせないテーブルビューの概要とインターフェースビルダーで固定レイアウトのテーブルの作り方を紹介します。加えてインターフェースビルダーでの画面切り替えのしくみと設定、それにアプリケーションデリゲートの使い方を説明します。

毎月札幌でiOSアプリ作りをアシストするセミナーをやっています。1時間にわたるセミナーの全内容を物理的に参加できない方のためにnote上で公開します。ぜひアプリ作りにチャレンジしてください。

iOSアプリを作ろうシリーズのセミナーは今後も月一回のペースで続けます。
詳細は connpass.com の 札幌Swift でご確認ください。そして機会があればぜひ参加してください。
アプリ作りプログラミング教育に関連する話題は 札幌Swift のfacebookページ で発信しています。

快技庵(かいぎあん)の高橋です。
1980年代後半からのMacのアプリを作ってきた現役開発者で現在は電子書籍などのiOSアプリを作っています。
note や Twitter のアイコンは、最初に作った電子書籍アプリ豊平文庫のアイコンにしています。

『iOSアプリを作ろう』シリーズ、今回は『テーブルビューと画面切り替え』です。

テーブルビューとは

設定アプリの画面や連絡先アプリの画面で使われているのがテーブルです。
iPhone の画面に最適化されています。
iOS では一覧表示のためだけでなく、メニューのような使われ方もされる重要な UI部品です。

テーブルビューの概要

テーブルは上下にスクロールできる一つのカラムを持っていて複数の行を表示します。
情報は行単位ですが、セクションで複数の行をグループ化できます。グループはABC順や五十音順などが多いです。
セクションには区切りとしてヘッダーフッターを持ち文字などを表示できます。

テーブルビューはナビゲーションビューコントローラーと組み合わせて使われるのがほぼデフォルトの使い方になっています。2段以上のグループもわかりやすく扱え、いつでも上位に戻れます。
電子書籍では 作家名の五十音別リスト で作家を選び 作家別の作品リスト から目的の作品を選び ダウンロード画面 の部分で「テーブルビューとナビゲーションビューコントローラーの組み合わせ」を使っています。

セクションとヘッダー表示の例

連絡先アプリは名前頭文字ABC順のセクションわけで実用性を確保しています。
図の例では H のセクションには二件の名前があり、ほかのセクションは一件です。
右端にインデックスも見えます。(インデックス表示もテーブルビューの機能ですが今回は触れません)

UITableView クラス

UITableView クラスは UIScrollView クラスを継承しています。(UIScrollView クラスは UIView を継承しています。)
プロパティもメソッドも多い高機能で複雑なクラスです。
表示にはデータソースのしくみを使います。操作などの対応はデリゲートを使います。(データソースとデリゲートについては5月のセミナーで解説します)

表示スタイル Plain

UITableView には二つの表示スタイルがあります。
スタイルはイニシャライザで指定します。途中でスタイルを変更することはできません。
連絡先アプリで使われているのは Plain スタイルです。
Plain スタイルではヘッダー表示は太字に強調され視認性は問題ありません。

表示スタイル Grouped

もうひとつの表示スタイルは Grouped です。設定アプリなどで使われています。
ヘッダーとフッターの表示は複数行表示が可能です。
ヘッダー・フッターはグレイの文字で表示されます。
英語表示ではヘッダーはすべて大文字で強調されますが、日本語では字種の変換はないため行とヘッダーの区別がしにくいです。

テーブルビューの構造

テーブルビューは、行のグループであるセクションの番号と、セクション内の各行の番号(Raw番号)で管理します。
各行をひとつのセルとして扱います。

セル

セルは行の表示専用のビューです。
UITableViewCell クラスは UIView を継承しています。

NeXT由来の macOS 用 Cocoa のテーブルビューでは、セルのクラスにビューより処理の負荷が軽い NSCell クラスを使っていました。(NSCell は NSView は継承していなかった)
一方後から登場した iOS では mac の良いとこ取りでビューの処理も洗練されたらしく iOS 2.0 からテーブルビューセルは UIView を継承しています。

セルの構造は1行を content と呼び、content の右側にアクセサリービューを持つ場合があります。
さらに編集中(エディットモード)は右側にデリートコントロールを持ちます。(今回は編集は扱いません)

四種類ある標準セル

セルは空っぽで何も表示しないもの以外に、四種類の標準セルがあります。
ラベルを一つ持つ Basic、右側に二つ目のラベルを持つ Right detail、二つ目のラベルを下に持つ Subtitle、右寄せ表示のラベルと左寄せdetail を持つ Left detail です。
Left detail 以外は画像を表示するイメージビューも持てます。画像を設定した場合は左側に表示し文字を表示する範囲は狭くなります。

https://developer.apple.com/documentation/uikit/uitableviewcell に標準セル内のレイアウトを解説している図が載っています。

UITableViewCell クラスのプロパティ

標準セルのラベルとイメージビューはプロパティでアクセスできます。
すべて読み出し専用です。
セルを標準のスタイルに設定すると適切な位置サイズに配置されます。

var textLabel: UILabel? { get }
var detailTextLabel: UILabel? { get }
var imageView: UIImageView? { get }

固定レイアウトの場合はこれらのプロパティを使うよりも、直接アウトレット接続するのが手軽でわかりやすいと思います。

contentView プロパティは独自のサブビューを配置するビューです。
var contentView: UIView { get }
backgroundView プロパティもありますが、セルの外観カスタマイズはいろいろ複雑なので初学者にはおすすめできません。
var backgroundView: UIView? { get set }
accessoryType プロパティは accessoryView に表示する標準アイコンのタイプを指定します。
var accessoryType: UITableViewCell.AccessoryType { get set }
var accessoryView: UIView? { get set }

UITableViewCell.AccessoryType

accessoryType に設定できる値は UITableViewCell.AccessoryType 型で、アイコンなしが .none、ディスクロージャーは .disclosureIndicator、インフォアイコンとディスクロージャーが .detailDisclosureButton、チェックマークは .checkmark、インフォアイコンが .detailButton です。

アクセサリビューに .disclosureIndicator でディスクロージャーを表示する行はタップに反応し詳細画面が右側からスライドして切り替わることをユーザーに示します

固定レイアウトのテーブルビュー

テーブルビューの表示は複数のメソッドに対応が必要で手間がかかります。
このため、行数や表示内容の変わらない場合はインターフェースビルダーの操作だけで作成できる仕組みが作られました。ここではそれを固定レイアウトのテーブルビューと呼びます。

固定レイアウトのテーブルビューの情報はストーリーボード内に保存されます。
固定レイアウトをインターフェースビルダーで設定する場合、テーブルビューのコントローラーは UITableViewController クラス(またはそれを継承しているクラス)でなければなりません。

インターフェースビルダーで固定レイアウトにするには、テーブルビューアトリビュートインスペクタで Static Cells を指定します
Static Cells とするとセクション数やセクション別の行数が指定可能になります。

インターフェースビルダーの画面では固定レイアウトのテーブルビューのセルやセルごとのラベルなどが自動配置されます。
そのラベルなどは自分で配置したラベルと同様に、自分のコードにアウトレット接続することもできます。

UITableViewController が必要

固定レイアウトでは UITableViewController が必要です。
インターフェースビルダーで UITableViewController の画面(シーン)をオブジェクトライブラリからドラッグ&ドロップで配置すると、UITableViewController 画面には  TableView が配置済みです。

通常のビューコントローラーまたはそれを継承しているクラスの画面にも TableView を配置できますが、固定レイアウトにするとエラーを表示します。

サンプルの作成手順

ここからは Xcode を使って固定レイアウトのテーブルサンプルを作成する手順を説明します。
次の手順で作業をすすめます。

❶ iOSの Single View App テンプレートでプロジェクト保存する
❷ Main.storyboard のデフォルトシーンを削除する
(これは最初の画面に固定レイアウトテーブルを表示するためです)
❸ Main.storyboard に UITableViewController を配置します
3-2 配置したシーンを Edit メニュー Embed in で Navigation Controller にエンベッドインしします
3-3、3-2 で配置した Navigation Controller を Initial View Controller にします
❹ ViewController.swift(ソースファイル)も不要なので削除する
(手順 ❷ で削除したシーンに対応するクラスなので不要です)

Xcode の Welcome to Xcode 画面の「Create a new Xcode project」で新規プロジェクトを作成します。
(Fileメニュー New > Projectでも同じです)

❷ デフォルトシーンを削除

テンプレートで保存したストーリーボードの唯一の画面(シーン)を削除します。
画面の上にバーを選択した状態で delete キーで削除します。
(UITableViewController の画面に差し替えるため、デフォルトの画面は不要になるので削除します)

❸ UITableViewController を配置

オブジェクトライブラリに「table」と入力し表示を絞り込みます。
「Table View Controller」を画面にドラッグ&ドロップし配置してください。

3-2 配置したシーンを Navigation Controller にエンベッド

配置した「Table View Controller」を選び、Edit メニュー Embed in サブメニューの Navigation Controller でナビゲーションコントローラーのルートビューコントローラーに設定します。
(Navigation Controllerと「Table View Controller」を適宜移動し横に並べてください)
次にNavigation Controller を選び、アトリビュートインスペクターで Is Initial View Controller をチェックしてイニシャルビューコントローラーにしてください。
(Is Initial View Controller のチェックを忘れるとアプリ起動時に何も表示しないのでご注意ください)

❹ ViewController.swift を削除

プロジェクトナビゲーターで ViewController.swift を選び delete キーで削除します。
確認アラートが表示されるので Move to Trash でhゴミ箱へ入れます。

Content を Static Cells に設定

「Table View Controller」シーンの Table View を選び、アトリビュートコントローラーで Content の設定を Static Cells に切り替えてください。(デフォルトは Dynamic Prototypes です)
選択はドキュメントアウトラインでおこなうと確実です。

Static Cells に切り替えるとインターフェースビルダー画面のドキュメントアウトラインに Table View Section が追加されます。

Table View Section

Table View の Content の設定を Static Cells に変更すると追加される Table View Section はストーリーボード専用のデータで、対応するクラスはありません。
ドキュメントアウトラインでは青いサイコロ状のアイコンを表示します。

ドキュメントアウトラインで Table View Section を選択しアトリビュートインスペクターを確認すると行数(Raws)の設定があります。

行数の設定は文字入力またはステッパー操作で増減できます。
今回のサンプルでは4に設定します。
ヘッダー文字列とフッター文字列は必要ならここで入力します。

ヘッダーに文字列を設定した場合はドキュメントアウトラインの Table View Section にヘッダーの文字列を表示します。(ヘッダーに入力した文字がTable View Section の名称となります)

セルの設定

Table View Section で設定した行数だけ Table View Cell が追加されます。
画面でも行がふえ、ドキュメントアウトラインでは Table View Cell が4件追加されています。

各セルのスタイル

Table View Cell を選択しアトリビュートインスペクターの Style を変更すると標準のセルに変更できます。

デフォルトではスタイルはカスタムになっていて行には何も表示されていません。

Basicスタイル

一番うえの行(Table View Cell)を選んでスタイルを Basic に変更するとラベルが一つ追加になります。ラベルにはデフォルトで「Title」と入力されています。ここを好みに変更してください。
もちろん日本語で入力も可能です。

Right Detail スタイル

スタイルを Right Detail に変更するとラベルが二つ追加になります。左のラベルにはデフォルトで「Title」と入力されていて、右のラベルには「Detail」と入力されています。どちらも好みに変更することができます。
2行目をカスタムから Right Detail に変更してください。
固定レイアウトの標準スタイルで追加になったラベルは、どれもアウトレット接続しコードで内容を設定できます。

Left Detail スタイル

Left Detail スタイルもラベルが二つ追加になりますがレイアウトが違います。文字サイズも小さくなっています。
3行目をカスタムから Left Detail スタイルにして確認してください。

Subtitle スタイル

Subtitle スタイルもラベルが二つ追加になります、上下に並ぶレイアウトとなります。
4行目をカスタムから Subtitle スタイルにして確認してください。

セルに画像を追加

テーブルの標準スタイルのセル(行)にはアイコンやサムネイルなどの画像を表示できます。

準備:先にプロジェクトの「アセット」に画像ファイルを登録しておきます。
アセットには複数の画像などを登録できます。

画像を表示したいセル(行)を選びアトリビュートインスペクターで Image のプルダウンメニューを表示すると、アセットに登録した画像のファイル名が並びます。このファイル名を選ぶとその画像をセルに表示します。

画像はそのまま表示されます。
余白などが必要な場合は画像側であらかじめ対応するのが楽です。

標準セルスタイルの設定例

ひとつだけ画像を設定した例です。
4つのセルにそれぞれ別のスタイルを順に設定しています。

アクセサリービュー

インターフェースビルダーのアトリビュートインスペクターでセルの Accessory を None 以外にするとアクセサリービューに標準アイコンを表示できます。

ここでは画面遷移を意味する Disclosure Indicator を1行目と2行目に設定します。

セル外見完成

Disclosure を表示した固定レイアウトのセルです。
タイトルには何も設定していませんが、適宜入力してください。

インターフェースビルダーを使った、固定レイアウトのテーブルビューの設定手順はここまでです。
次にコードを追加しサンプルを仕上げて行きましょう。

コードを追加 その1

最初に表示する画面のビューコントローラーとして UITableViewController を継承したクラスを追加します。
手順を追って説明します。

1-1 ソースファイルを追加

ナビゲーションエリアに + ボタンを使ってソースファイルを追加します。
Main.storyboard と同じグループに追加するため、Main.storyboard を選択した状態でナビゲーションエリア一番下の + ボタンクリックしてメニューを表示させてください。
メニュー一番上の File… を選んでください。

1-2 Cocoa Touch Class を選択

一番上で「iOS」が選択状態であることを確認し「Cocoa Touch Class」を選択し「Next」ボタンをクリックしてください。

1-3 UITableViewController のサブクラスとして保存

画面の Class: はクラス名の入力でそのままファイル名となります。
Subclass of: で継承するクラスを選択できます。先に UITableViewController を選んでください。
次にクラス名は MainTableViewController として保存してください。
(アプリの最初に表示される画面のビューコントローラーなのでこの名称にしました)

1-4  不要なコードの削除

保存した MainTableViewController.swift のコードがエディタ画面に表示されるはずです。
少し下にスクロールすると、データソースのコードが入力済みです。
固定レイアウトの場合はこのコードは不要です。
// MARK: - Table view data source の行から下はの行は全て選択し delete してください。

ここで削除するデフォルトのデータソースコードはセクション数ゼロを返すコードです。これが残っているとインターフェースビルダーでセクション数や行数を設定しても、実行すると何も表示しません。

ここから先は

10,523字 / 33画像 / 1ファイル
この記事のみ ¥ 500

今後も記事を増やすつもりです。 サポートしていただけると大変はげみになります。