げっとシステムログ

WEB開発メモ

TableView の使い方

とりあえずものを表示させてみる

  • セルの設定を行う
    • identifier の設定
    • セルのクラスの設定
  • 描画のためのコード
    • NSObject, UITableViewDataSource

セルの設定

セルに identifier を設定する

f:id:shun-fix9:20160501131621p:plain

カスタムクラスがあるならそれの設定も
(サンプルには載っていないけど、今回はラベルを幾つか配置しているのでカスタムクラスでやっている)

f:id:shun-fix9:20160501131626p:plain

セルの種類が幾つかある場合は、 Prototype Cells の数を増やすと設定できるようになる

f:id:shun-fix9:20160501131846p:plain

outlet の設定

tableView を outlet でコードに紐付ける

f:id:shun-fix9:20160501132128p:plain

tableView を右クリックすると outlet のやつが出てくるので、 Referencing Outlets の部分から右側のコードまで引っ張って紐づけを行う

f:id:shun-fix9:20160501132414p:plain

右側のコードが別なやつだった場合は右上のパンくずリストみたいなやつから選びなおせる

描画のためのコード

if resultsDataSource == nil {
  resultsDataSource = ResultsDataSource()
  resultsTable.dataSource = resultsDataSource
}

tableView に dataSource を設定する

ViewController に UITableViewDataSource を実装する、というサンプルが結構あるが、これは ViewController が一つの TableView しかもっていない場合に適切なもので、中に他のコンポーネントがある場合は別なクラスにするのが良いはず

というわけで DataSource クラスは別に用意する

import Foundation
import UIKit

class ResultsDataSource: NSObject, UITableViewDataSource {

  private let tasks = [0,1,2,3]

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    switch indexPath.section {
    case 0: return taskCell(tableView, indexPath: indexPath)
    case 1: return timeCell(tableView, indexPath: indexPath)
    default:
      return tableView.dequeueReusableCellWithIdentifier("time", forIndexPath: indexPath)
    }
  }
  private func taskCell(tableView: UITableView, indexPath: NSIndexPath) -> UITableViewCell {
    let task = tasks[indexPath.row]
    let cell = tableView.dequeueReusableCellWithIdentifier("task", forIndexPath: indexPath)
    if let taskCell = cell as? ResultTaskCell {
      // セルの描画
    }
    return cell
  }
  private func timeCell(tableView: UITableView, indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("time", forIndexPath: indexPath)
    if let timeCell = cell as? ResultTimeCell {
      // セルの描画
    }
    return cell
  }

  func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 2
  }

  func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section > 0 {
      return 2
    } else {
      return tasks.count
    }
  }
}

セクション二つの構成
最初のセクションは二行、もう一つのセクションはタスクの数だけ表示
という構成

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell が肝

  1. tableView.dequeueReusableCellWithIdentifier("time", forIndexPath: indexPath) でセルを取得
  2. if let timeCell = cell as? ResultTimeCell で目的のクラスにして描画

dequeueReusableCellWithIdentifier の第一引数には、先に設定しておいた identifier を指定する
カスタムクラスを使用する設定にしておくと、このクラスにキャスト出来るようになる

これで、とりあえず表示だけはなんとかなるはず

あとはタップされたら何かする、とかだけれど、それは DataSource ではなくて Delegate でやるんだよね・・・
今回は TableView でそういうアクションをやらなかったのでコードがありません

ものが表示されない・・・というときは

  • TableView の背景、 Cell の背景を白、黒以外の色にしよう
  • 文字の色を白、黒以外の色にしよう

文字や背景色が親の色と一緒になって見えない、というハマり方をした
あと、 hidden になってたり、他の要素に隠れているのでは?という疑心暗鬼とか

例えば TableView の背景を赤にして、文字色を青にすれば、かなりきつい配色になるので表示されていないならすぐにわかる