Help us understand the problem. What is going on with this article?

XibファイルでTableViewを実装する

More than 3 years have passed since last update.

TableViewを実装する際に画一的な見た目のセルではなく、一つ一つのセルをカスタマイズしたい時があるかと思います。

僕の場合は、個人アプリのホーム画面にXibファイルで作成したTableViewを採用していますが、結構色んなことができて非常に便利でした。

今後、他のアプリでも活用する機会が増えると思ったので、今回はこれについて書いていきたいと思います。

できたもの

カスタムセルを使い、異なるデザイン(とは言えLabelとHeightが異なるだけ)のセルをtableView上に描画しています。

CustomTableView.gif

実装

このソースはGithubでも公開しているので、ぜひこちらも見てみて下さい。

Viewを追加

HeaderViewとTableViewをそれぞれStoryBoardに追加します。

Screen Shot 2017-09-08 at 9.34.13.png

Xibファイル追加

次にTableViewに表示したいCellの数だけXibファイルを追加していきます。
僕の場合はXibフォルダーを追加してその配下にXibファイルとswiftファイルをまとめて入れています。

またXibファイルの作成は、通常の新規ファイル追加をする時に表示されるダイアログのAlso create XIB fileにチェックをいれるだけでXibファイルが生成されます。

Screen_Shot_2017-09-07_at_11_10_22.png

これで作成したXibファイルでセルを自由にカスタマイズできるようになりました。

Screen Shot 2017-09-08 at 9.49.00.png

CellのHeightを可変にする

次にカスタマイズしたCellのHeightを可変にする処理を行います。

TableViewを配置しているViewControllerのviewDidLoad()内に下記のメソッドを追記します。

ViewController.swift
override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.estimatedRowHeight = 100
}

estimatedRowHeightはTableViewCellの推定高さを指定し、更に高さが変わるCellの場合には自動的に高さを調整する役割を持ちます。

この時に指定するデフォルトの高さは任意で問題ないので今回は100としています。

カスタムセルを描画する

ここまででカスタムセルの作成とTableViewへ描画する際の準備が整いました。
次に行うのは、カスタムセルをTableViewへ描画する処理です。

TableViewを設置しているViewControllerのviewDidLoad()内に下記を追加します。

ViewController.swift
var tableViewArray = [UITableViewCell]()

...

override func viewDidLoad() {

    self.tableView.register(UINib(nibName: "FirstTableViewCell", bundle: nil), forCellReuseIdentifier: "FirstTableViewCell")

    guard let firstTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "FirstTableViewCell") as? FirstTableViewCell else {
        return
    }
    self.tableViewArray.append(firstTableViewCell)

} 

tableViewArrayは後からセルを描画する時の処理に活用するので、ここで追加処置を入れておきます。

また、上記はFirstTableViewCellのみ追加していますが、作成したカスタムセルの分だけこの処理を追加してください。

TableViewのメソッドを追加

TableViewは下記の2つのメソッドの実装が必須となっています。
1. tableView(_ tableView: UITableView, numberOfRowsInSection)
2. tableView(_ tableView: UITableView, cellForRowAt)

今回カスタムセルを描画するTableViewでは、FirstTableViewCellSecondTableViewCellThirdTableViewCellの3つのセルを描画するため、下記の様な実装となります。

ViewController.swift
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return tableViewArray.count
}

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

    let tableViewCell = self.tableViewArray[indexPath.row]

    if tableViewCell is FirstTableViewCell {
        return tableViewCell

    } else if tableViewCell is SecondTableViewCell {

        return tableViewCell

    } else if tableViewCell is ThirdTableViewCell {

        // no selectable
        tableViewCell.selectionStyle = UITableViewCellSelectionStyle.none
        return tableViewCell

    }

    return UITableViewCell()
}

.selectionStyleUITableViewCellSelectionStyle.noneを指定すると、セルタップ時に選択できなくすることができるので例として書いています。この処理を入れているので、先に紹介したできたものではThirdTableViewCellが選択状態になっておりません。

ヘッダービューに選択されたセルの名前を出力

TableViewでは、セルが選択された時に呼び出されるメソッドがあるので、そこで選択されたセルの名前を描画する様にします。

ViewController.swift
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    headerView.text = tableView.cellForRow(at: indexPath as IndexPath)?.className

}

.classNameは独自に追加したextensionを活用しています(以下参照)。

import Foundation

extension NSObject {
    class var className: String {
        return String(describing: self)
    }

    var className: String {
        return type(of: self).className
    }
}

ここまでで最初にできるもので提示したTableViewの描画が完成です。

おまけ

先ほどまでの処理で作成したTableViewのままでも充分活用できるのですが、もう少しカスタマイズを加えたいと思います。

例えばセルの線を消したり、セルをグループ化したりといったことができます。

セルの線削除

作成したカスタセルのawakeFromNib()内に下記の処理を追加します。

FirstTableViewCell.swift
separatorInset = UIEdgeInsets(top: 0, left: bounds.width, bottom: 0, right: 0)

カスタムセルの線を全て削除すると下記の様になります。

IMG_3534.PNG

セルのグループ化

セルのグループ化を行うと、下記の不要なセルを非表示にして表示されているセルを1つのパーツとしてグループ化できます。

Main.storyboard > TableView > Attributes inspector > Style > Grouped

Screen_Shot_2017-09-08_at_10_51_30.png

IMG_3532.PNG

この状態だとTableViewの上部に不要なセル(ヘッダービュー下の灰色のセル)が表示されてしまいます。
これを削除したい場合は、TableViewを設置しているViewController内で下記を追記してください。

ViewController.swift
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    // Erase header cells
    return .leastNormalMagnitude
}

これで見た目も大分すっきりしました。

この他にもTableViewで表現できることはたくさんありますので、興味ある方はぜひ調べてみて下さい。

yamataku29
init株式会社CEO&CTO / フリーランス / iOS/Androidエンジニア / MENTAでプログラミングを教えている URL: https://menta.work/plan/584 / 元BtoB営業マン / ハッカソン全国大会準優勝(SPAJAM2017) / 個人iOSアプリリリース&収益化 / 元アーチェリー日本代表
https://init-inc.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした