UI考：なぜそのセルには押せる感があるのか

# この記事の目的

セル（UITableViewCell）は iOS においてもっとも一般的なビューのひとつです。セルを利用することで、コンテンツの表示、選択、スイッチやボタンの配置、テキストフィールド、ナビゲーションを実装することができます。この辺りの具体的な実装例は『設定』や『Apple Store』が参考になるでしょう。セルにはさまざまな役割を与えられますが、どのような作法に従ってデザインされているのかよく理解する必要があります。

セルの一般的な利用作法は [iOS Human Interface Guidelines](https://developer.apple.com/ios/human-interface-guidelines/ui-views/tables/) で解説されていますが、私はこれを読んだだけでは十分に理解が及ばなかったため、iOS 標準アプリの事例からセルのデザインについて考察したものをまとめました。この記事では iOS の標準的なセルのデザインパターンを探り、自身のアプリにどう活かせるのかの土台となるよう考察してみます。

UICollectionViewCell もセルと呼称されますが、今回は UITableViewCell に限定して考えます。

# セルとは何か

<img width=375 src="https://qiita-image-store.s3.amazonaws.com/0/3603/1a9d7293-ff28-4807-0203-c653a944fcda.png">


セルは情報の細胞です。ひとつの情報のまとまりが“セル”として表現されます。セルはそれ単体ではほとんど意味をなさず、セルの集合＝テーブルビューによってはじめて機能するようになります。このような情報の細胞が集まって構成されるのがテーブルビューであり画面であり、そしてアプリケーションです。

テーブルビューセルが細胞というメタファーで表現されることには少々違和感があるかもしれません。iPhone のテーブルビューはセルがただ上から下に一列で並ぶので、細胞が敷き詰められているようには見えません。どちらかというとリストです。ここで、iOS の親である Mac OS X を見てみましょう。UITableView に相当する NSTableView にもセルという概念が存在します。NSTableView ではセルはとても細胞らしく振る舞われます。

<img width=875 src="https://qiita-image-store.s3.amazonaws.com/0/3603/2c51ad98-caee-fb8d-c365-4ba69b1f1eab.png">
*Finder のリスト表示はテーブルビュー（アウトラインビュー）で表現される。行ごとの枠一つ一つがセルで実装されている*
![](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TableView/Art/SplitOut_View.jpg)
*NSTableView の構造: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TableView/TableViewOverview/TableViewOverview.html*

iPhone の画面は縦長であることと、その利用のされ方が PC とは大きく異なるため、モバイルに適したテーブルビューとしてリデザインされました。歴史を振り返って UITableView は Cocoa (Mac OS X) の NSTableView から来ているものと仮定すると、UITableView はモバイルに適した一列表示に特化した廉価版 NSTableView と解釈できます。

元来 NSTableView のセルはビューではありませんでした。Cocoa における“セル”はビューとは別の NSCell という情報で扱われ、基本的にセルはどんなビューにも入り込むことができ、実際の描画とイベント処理はビューが行うものとなっていました。セルにはボタンとしての見た目を決める「描画処理」を記述したメソッドだけを実装すれば良いものでした。この仕組みがあるおかげで、ボタンセルをそのままテーブルビューに設置すればボタンの見た目をしたセルを割と簡単に実現することができました。セル単体では意味をなさないけれども、ビューに入り込むことでボタンとしての機能と見た目が成り立つようになっていて、その設計思想はまさに細胞というのに相応しいものです。

しかしここで、NSCell を有しないビュー、例えばプログレスインジケーターをテーブルビューに並べることは非常に難しいという問題が浮上します。Safari のダウンロードパネルのようなテーブルビューは正攻法では作ることのできないビューだったので、実装にはなかなか苦労したものです。

![](https://qiita-image-store.s3.amazonaws.com/0/3603/b59b1141-b392-2cf8-09d1-777d68971f33.png)
*現在のダウンロードパネルは違うかもしれないが、かつてのコレは実装がカオスだった予感がする*

NSCell と各種ビューでそれぞれ別のクラスとして実装しなければならないこと、そこまで細胞的な汎用性は必要ないにもかかわらず NSCell の仕組みに従う必要があること、NSCell が NSObject 直下のクラスなのにビューで表示する内容の描画処理を実装する必要があること、ビューに依存する処理は難しいこと、iOS が登場して UITableViewCell のような直感的な仕組みに慣れてしまったことなど……。とにかく NSCell はレガシーかつ扱いづらいということで、最近はビューベースドセルという iOS 風の仕組みが導入されています。要はビューとしてセルを扱えるようになった、ということですね。

iOS 側からはよく見えなくても、Mac OS 側からはセルとは何なのかがよく見えてきました。
ここからは iOS に戻ってセルのデザインパターンを考えてみます。

# セルのデザインとシグニファイア

純正アプリはそのほとんどが UIKit 標準の状態で実装されているので、セルの利用作法を学ぶ良いお手本となります。それらを観察して見えてきたデザインの構造について以下にまとめました。

## 項目のリスト表示

セルの原則は情報を均一に配置することです。**同じセクションに並べられる情報は同等になります。**

『設定』アプリのように、同一テーブル内で情報を区切って表示するには『グループスタイル（Grouped）』を採用します。グループスタイルでは連絡先で見られるようなセクションヘッダーやインデックス（索引）は利用できません。『設定』アプリのような用途でテーブルを用いるにはこのグループスタイルを採用します。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/fb82afd2-b1fa-d417-d869-b22d714edbb4.png">
*グループスタイル*

主にデータやコンテンツを並べる用途でテーブルを用いるには『プレーンスタイル』を採用します。このスタイルでは『連絡先』アプリようにセクションヘッダーやインデックスを利用することができます。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/5d054977-0740-e546-ea2c-452d2dfa487b.png">
*プレーンスタイル：セクションヘッダーとインデックス*

## ディスクロージャーを伴うセル

セルのアクセサリーにはディスクロージャーを配置できます。ディスクロージャーはその行と別の情報との連続的な関連性を示しています。セルにディスクロージャーが表示されることで、**ユーザーはセルをタップすると関連する情報を扱う別のテーブルに遷移できることを認識できます。**これはドリルダウン（プッシュ遷移）に限らずモーダルビューによる遷移でも同様です。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/97b47f8e-56d5-16e8-2dad-b6af8b48ef3c.png">
*ディスクロージャーを伴うセルは明らかにタップ可能*

遷移先がテーブルではないセルにディスクロージャーを用いるのはあまり好ましくない気がしますが、その行と関連するテーブル以外の情報を表示する画面に遷移する程度であれば許容されるでしょう。ライセンス条文を記述した WebView へ遷移するような場合にもディスクロージャーを利用することができます。SFSafariViewController はモーダルで遷移しますがそのトランジションがあえてドリルダウンのように演出されるため、ディスクロージャーとは相性が良さそうです。

逆にディスクロージャーを利用できない場面、例えると、セルをタップしたら Safari で web ページを開くといった明らかに連続性が断ち切られるような動作です。ディスクロージャーはそのセルに関わる情報への関連性を示していますから、別のアプリに遷移するには後述する『アクションを伴うセル』を用いるか、セクションヘッダー／フッタービューに配置したボタンで対応します。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/f6adbb7b-0a95-657c-5778-d0df0160bde6.png">
*セクションフッターに配置した、web ページを開くボタン*

## 値を表示するセル

アクセサリーに詳細ラベルを伴うセルでは値を表示することができます。作法として、左側のラベルは左寄せであるのに対し、右側の詳細ラベルは右寄せであるべきです。色がグレーであると編集ができないことを意味します。**ユーザーはこのようなセルを見たとき、タップできないセルだと認識します。**

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/5d9e3314-0556-fe9e-59d4-d2c166c8441c.png">
*値表示セルはタップ不可能*

次の例ではディスクロージャーを併用しているので、このセルはタップすることができ、関連するテーブルで情報を編集できるということを示唆しています。関連テーブルの結果がセルの値として表示されています。**ユーザーはこのようなセルを見たとき、セルをタップした先に何かしらの選択肢や編集機能があることを察します。**

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/88871e02-165f-f7d0-5311-28233876742c.png">
*ディスクロージャーを伴う値表示セルはタップ可能*

値を表示するセルは普通タップできないものですが、シリアル番号のように、どこかで入力が必要になるかもしれなくて手入力が困難な情報を表示する場合は、そのセルをタッチした時にコピーメニューを表示するというインタラクションを実装してあげると親切です。
<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/cbbf8dab-b850-4355-06e0-cfed3566666d.png">
*シリアル番号をコピーできるセル*

## スイッチ・ステッパーを伴うセル

セルのアクセサリーにはスイッチやステッパーを配置できます。**このようなセルはタッチに反応しません。アクションはスイッチ・ステッパーのみに作用します。**もし押下（ハイライト）できてしまったらそれは実装ミスの疑いがあります。

なお、UISwitch は UITableView のみで使用しなければならないとされています。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/087ec4ad-ae17-7047-c55b-62fd2275a49d.png">
*スイッチ・ステッパーを伴うセルは明らかにタッチ不可能。ただしアクセサリー部分のみ作用する*

スイッチを用いる場合はその状態が一目瞭然であるため、スイッチに応じてラベルの表記を『オン』『オフ』と切り替えて表示するようなことは必要ありません。

## コントロールを伴うセル

スイッチやステッパー以外のより大きなコントロールはアクセサリーではなくセルに直接配置します。**このようなセルはタッチに反応しません。アクションはコントロールのみに作用します。**

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/f62bc959-4d04-3f82-8bcd-e0eaff0dcb9a.png">

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/1e224b45-f60a-1e75-a139-acb359a44e51.png">


## 詳細ボタンを伴うセル

スイッチ・ステッパーを伴うセルに似ていますが、代わりにボタンを配置したセルです。このセルはタッチに反応できます。セルとボタンのアクションは個別に実装できます。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/122b78c4-8d32-e4a3-1453-f0ebe183f6af.png">

このようなアクションが二つ以上あるセルはユーザーを戸惑わせる可能性があるため扱いには要注意です。Wi-Fi 設定の例ではうまく対処していて、セルのタップでは選択肢としてのセルのように振る舞い、詳細ボタンは詳細設定への遷移アクションとして振る舞います。もし選択されている場合はセルのタップでも詳細設定に遷移します。

## 選択肢としてのセル

セルのアクセサリーにはチェックマークを配置できます。チェックマークを用いたテーブルでは、少なくともそのセクションはすべてチェックマークが表示されうる選択肢として機能しなければなりません。**ユーザーはセルを選択肢として認識したとき、そのテーブルを押下可能な候補一覧と見なします。**このようなテーブルではセルがタッチ可能なものでなければなりません。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/8453a8f4-c6e8-335c-93cb-faa92160eb01.png">
*チェックマークがあるので、明らかにタップ可能な選択肢*

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/1f8709b7-3c6f-74a3-70a0-121a1c6b1509.png">
*一見チェックマークはないが、連続的な数値が並んでいるのでこれらがタップ可能な選択肢であると察することができる*

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/431fa23c-f60c-8672-9fcf-a9838057fbb4.png">
*スイッチではなく『オフ』を選択肢として用意している例*

もし選択肢が一つしかなくトグルのような機能をデザインするには、チェックマークの代わりにスイッチの利用を検討してください。
<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/187678af-02bc-e977-f3ca-baf4ae627a0b.png">

### 左チェックマーク？

『設定』アプリの Wi-Fi やサウンド設定画面ではこのような左チェックマークのセルが見られます。チェックマークはアクセサリーに配置するものとされていますが、左チェックマークは標準の機能では提供されていないので、イメージビューなどを利用して独自に実装しているのでしょう。Wi-Fi 設定画面ではアクセサリーに詳細ボタンを配置しているためチェックマークを左側に寄せているのだと思われます。サウンド設定画面に関しては、本来の右チェックマークではなく左チェックマークを用いている理由は正直言ってよくわかりませんでした。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/aeb37849-d9af-1826-5c42-eb8bbffe7cf6.png">


## アクションセル

**アクションをセルに持たせるにはテキストを Tint Color などで着色したセルを用います。**iOS では Tint Color で着色された要素はボタンと認識できるので、これはほぼボタンと言っても良いでしょう。このようなセルはタップしても関連テーブルには遷移しません。テーブルに行を追加するアクション、情報を削除するアクション、web ページを Safari で表示するアクションはこのアクションセルで実装します。アクションが破壊的であるなら文字色は Tint Color ではなく Destructive, 赤色にすると良いでしょう。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/1708d9ec-5110-d901-9c96-0364838a0c67.png">

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/08387786-9929-4e1e-43a3-27c753596b82.png">

アクションセルが無効な場合は、色を disable と同じグレーにしてタップできないことを説明します。
<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/dd425e95-970c-2da6-a98a-4800ac593e5d.png">
*これ以上指紋を登録できないので、追加がグレーになっている*


## テキストフィールド型セル

セルそのものにテキストを入力できるセルです。テキストフィールドには幾つかのパターンがありますが、コンテクストに合わせてデザインされているように見えます。一般には次のものが用いられます。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/f9477c11-fcfd-cf60-cb1e-43dbc02cee7e.png">
*ラベル付き左寄せ*
<br/>
<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/0de2b70e-5772-f27b-050b-ed33c3860f30.png">
*ラベル付き右寄せ*
<br/>
<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/8f6fe33d-b8bf-b85c-b4b4-2b44a7841661.png">
*ラベルなし左寄せ*
<br/>
テキストフィールドにはプレースホルダーが記入されていて、**ユーザーはプレースホルダーを見てこれが文字入力可能なテキストフィールドだと理解することができます。**書式を記入しておけばそれが何を入力すべきフィールドなのかも理解しやすくなります。

左寄せと右寄せの違は正直に言ってよくわかりませんでした。何か明確な作法が実は隠れているのかもしれないし、特に理由なんてなく、案外担当者の気分で違いが生まれているのかもしれません。

### そこに至るコンテクストからセルの意味を理解する

VPN 構成を設定するこの画面では「ラベル付き左寄せ」が用いられていますが、プレースホルダーが無いセルはこれがテキストフィールドなのかただのセルなのか、一目では区別がつきません。**ユーザーはラベルの意味とこの画面でのコンテクストを理解して初めてそれらがテキストフィールドであろうと察することができます。**

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/cb4c50ba-209d-b67b-f89a-eba70510504f.png">
*これらだけだとテキストフィールドなのかただのセルなのか区別がつかない*
<br/>
<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/e2375125-0f11-20d8-80f9-8285815eedab.png">
*全体を見渡せば『おそらく入力可能なセルだろう』と察することができる*

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/18ec4c04-c2c9-a64a-1dd2-7079e4afe9ef.png">
*実際にタップしてみるとテキストフィールドだとわかる*

# セパレーターの隙間

iOS 7から、セルのセパレーター（セルの境界線）の左側に隙間が空くようになりました。
<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/fb82afd2-b1fa-d417-d869-b22d714edbb4.png">

セルの左端ではなく文字列の始まりに合わせて線を引くと視覚的に開始点が揃って目線が文字列に向かうので読みやすくなります。横書き文を右から左に読む言語ではこれが反転します。また、セルを完全に区切らないことでこれらが連続的な情報であるということも比喩的に表現されているように思えます。

さらに踏み込むと、セパレーターの隙間が情報に階層構造を生み出し、同一セクション内であってもグループ分けと似たような情報の分類が行えます。

<img width="375" src="https://qiita-image-store.s3.amazonaws.com/0/3603/b76d2a54-fb21-12cb-6c56-0705c84fbee0.png">
*1本目のセパレーターは左端まで詰めているが、2本目以降には左端に隙間がある*