【Delegate】TableViewをUIViewControllerで実装する方法を解説

iOSアプリにおいてほぼ必ず登場するTableViewだけど、そもそもTableViewを実装する方法は次の二通りがあるよ。

  • UIViewControllerでTableViewを実装する方法
  • UITableViewControllerでTableViewを実装する方法

前者のやり方の方が後者のやり方に比べて若干工数がかかるが、汎用性が高い実装をすることができるため多く使われているよ。よってこの記事では前者の方法を解説することにするよ。

UIViewController上でTableViewを実装する流れ

実装の流れをざっくりとリスト化すると下のようになるよ

  1. StoryboardとViewControllerの関連付け・outlet接続
  2. UIViewControllerのプロトコル拡張
  3. delegateメソッドの実装
  4. delegate・dataSourceの設定

このリストに沿って手順を説明していくよ。

下準備

  • 新しいプロジェクトを作成
  • MainViewControllerMain.storyboardの二つのファイルを作成
  • Main.storyboardにUIViewControllerを配置して、さらにその上にTableViewを貼り付ける
  • 「Is Initial ViewController」にチェックマークを入れる(チェックマークが入ると下画像の「→」マークが表示される)

  • 「Targets」→「Deployment Info」→「Main Interface」をMainに設定

手順1. 関連付けとOutlet接続

手順1で行うことは次の二つだよ。

  • StoryboardとViewControllerの関連付け
  • TableViewのOutlet接続

・StoryboardとViewControllerの関連付け

まずはStoryboard常に表示されているViewControllerとコード上のViewControllerの関連付けを行うよ。
Storyboard上の右メニューを開いて「Custom Class」→「Class」から設定できるよ。下画像のように「Inherit Module from Target」にチェックマークが付いていれば正しく設定できているはずだよ。正しく関連付けがされていないと次に説明するOutlet接続もうまくいかないから注意。

・UITableViewのOutlet接続

関連付けを行ったらStoryboard上に配置したTableViewのOutlet接続を行うよ。controlを押しながらドラッグアンドドロップして設定するやつだよ

今回はtableViewという変数として接続しているよ

class MainViewController: UIViewController {  

    @IBOutlet weak var tableView: UITableView!  
    //以下略  
}  

手順2. ViewControllerのプロトコル拡張

1に続いて手順2ではUITableViewのdelegateメソッドを実装するためにUIViewControllerのプロトコルを拡張するよ。大半の人が「Delegateってなんだ!?」と疑問に感じると思うのだけれどこれについては後述するとして、まずは手順を説明するよ。

class MainViewController: UIViewController {  
    //省略  
}  

// MARK: - UITableViewDelegate, UITableViewDataSource  
extension MainViewController: UITableViewDelegate, UITableViewDataSource { }  

Exntensionを使うことでUIViewControllerをUITableViewDataSourceUITableViewDelegateの二つのプロトコルに準拠させたよ。これによって各プロトコルに用意されているdelegateメソッドを呼び出せるようになるよ。そしてこの時点ではエラーが発生することになるけど問題ないよ

手順3. Delegateメソッドの実装

手順2でUIViewControllerをUITableViewDelegate準拠させたことによって、UIViewControllerにDelegateメソッドが実装できるようになったよ。

UITableViewのデリゲートメソッドまとめを眺めると様々なDelegateメソッドが用意されていることがわかるけど、その中でも下の二つを定義するメソッドは必ず必要になるよ。逆を言えば最低限この二つのメソッドさえ実装できれとりあえずTableViewは実装できることになるよ

  • 行数を定義するnumberOfRows
  • セルの中身を定義するcellForRowAt

上の二つについてどのように実装するかを順次解説していくよ

numberOfRowsで行の数を定義する

このメソッドについてAppleの公式ドキュメント
から実装を見ると、sectionという引数を取り返り値型はIntとなっているよ。考えてみるとnumberOfRowsは行「数」を定義するのだから、返り値がInt型になるのは当たり前のことだよね

func numberOfRows(inSection section: Int) -> Int  

シンプルに行数の数字を返せば良いよ。例えば5行(5つのCell)にしたいときはこう

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {  
        return 5  
    }  

cellForRowAtでCellの中身を定義する

このメソッドについてAppleの公式ドキュメントから詳しい実装を見てみるとindexPathという引数をとって、返り値型はUITableViewCellとなっていることがわかるよ

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell  

indexPathについての説明は少し長くなるから別の記事に譲るよ。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {  
    let cell = UITableViewCell()  //あらかじめ用意されているCellクラスを使用しています。     
    return cell  
}  

今回はUIKitであらかじめ用意されているCellクラスを使っているが、自前で用意したカスタムCellを使うことが圧倒的に多いよ。カスタムCellを使ったTableViewの実装はまた別の記事で説明するつもりだよ。

手順4. Delegateの設定

再確認するけどここまで本来的にはUITableViewControllerで実装を行うはずのUITableViewをUIViewControllerで実装してきたよ。UITableViewControllerの実装をUIViewControllerにdelegate(移譲)したことを示す必要があるよ。
この設定を行うとDelegateメソッドで行った実装がしっかりと反映されて描画されるよ。delegateの設定を行う方法は次の二種類あるよ。

  • コードで設定する方法
  • Storyboardで設定する方法

どちらのやり方でも問題ないのだけどViewControllerの記述はなるべく減らすのがベターなので、自分としてはコードではなくStoryboardから設定する方法を推奨するよ
また、「Delegateってなんだ??」という方も少なからずいると思うからその方はDelegateとその必要性について解説を読んでもらえるとわかってもらえると思うよ。ではそれぞれのやり方を順次解説するよ

・Storyboradでdelegate・dataSourceの設定をする方法

TableViewを右クリック(二本指クリック)し、delegateとdataSourceの設定を行うよ。画像のように「Outlets」の項目内の「dataSource」と「delegate」がMainViewControllerに紐付いていれば正しく設定できているよ

・コードでdelegate・dataSourceの設定する方法

下のようにtableView.delegate = selftableView.datasource = selfと記述すると良いよ。ちなみにこの場合のselfMainViewControllerを指しているよ

class MainViewController: UIViewController {  
    @IBOutlet weak var tableView: UITableView!  

    override func viewDidLoad() {  
        super.viewDidLoad()  
        tableView.delegate = self  //ココ  
        tableView.dataSource = self  //ココ  
    }  
}  

まとめ

  • delegateの設定を行い、delegateメソッドを実装することでUIViewController上にTableViewを実装できる
  • extensionを用いてUIViewControllerを UITableViewDelegateUITableViewDateSourceの二つのプロトコルに準拠させることで、TableViewのDelegateメソッドを実装することができる
  • TableViewを実装するにあたって最低限実装が必要なDelegateメソッドは次の二つある
    • セルの個数(行数)を定義するNumberOfRows
    • Cellの中身を定義するCellForRowAtIndexPath

最後までご覧いただきありがとうございました

こっちは真面目に作ってます。笑

サクっとプログラミング

iOSアプリ開発のあれこれがまとまるwebサイト