TableViewを実装する際に画一的な見た目のセルではなく、一つ一つのセルをカスタマイズしたい時があるかと思います。
僕の場合は、個人アプリのホーム画面にXibファイルで作成したTableViewを採用していますが、結構色んなことができて非常に便利でした。
今後、他のアプリでも活用する機会が増えると思ったので、今回はこれについて書いていきたいと思います。
できたもの
カスタムセルを使い、異なるデザイン(とは言えLabelとHeightが異なるだけ)のセルをtableView上に描画しています。
実装
このソースはGithubでも公開しているので、ぜひこちらも見てみて下さい。
Viewを追加
HeaderViewとTableViewをそれぞれStoryBoardに追加します。
Xibファイル追加
次にTableViewに表示したいCellの数だけXibファイルを追加していきます。
僕の場合はXib
フォルダーを追加してその配下にXibファイルとswiftファイルをまとめて入れています。
またXibファイルの作成は、通常の新規ファイル追加をする時に表示されるダイアログのAlso create XIB file
にチェックをいれるだけでXibファイルが生成されます。
これで作成したXibファイルでセルを自由にカスタマイズできるようになりました。
CellのHeightを可変にする
次にカスタマイズしたCellのHeightを可変にする処理を行います。
TableViewを配置しているViewControllerのviewDidLoad()内に下記のメソッドを追記します。
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 100
}
estimatedRowHeight
はTableViewCellの推定高さを指定し、更に高さが変わるCellの場合には自動的に高さを調整する役割を持ちます。
この時に指定するデフォルトの高さは任意で問題ないので今回は100としています。
カスタムセルを描画する
ここまででカスタムセルの作成とTableViewへ描画する際の準備が整いました。
次に行うのは、カスタムセルをTableViewへ描画する処理です。
TableViewを設置しているViewControllerのviewDidLoad()内に下記を追加します。
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つのメソッドの実装が必須となっています。
- tableView(_ tableView: UITableView, numberOfRowsInSection)
- tableView(_ tableView: UITableView, cellForRowAt)
今回カスタムセルを描画するTableViewでは、FirstTableViewCell
、SecondTableViewCell
、ThirdTableViewCell
の3つのセルを描画するため、下記の様な実装となります。
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()
}
※.selectionStyle
にUITableViewCellSelectionStyle.none
を指定すると、セルタップ時に選択できなくすることができるので例として書いています。この処理を入れているので、先に紹介したできたもの
ではThirdTableViewCellが選択状態になっておりません。
ヘッダービューに選択されたセルの名前を出力
TableViewでは、セルが選択された時に呼び出されるメソッドがあるので、そこで選択されたセルの名前を描画する様にします。
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()内に下記の処理を追加します。
separatorInset = UIEdgeInsets(top: 0, left: bounds.width, bottom: 0, right: 0)
カスタムセルの線を全て削除すると下記の様になります。
セルのグループ化
セルのグループ化を行うと、下記の不要なセルを非表示にして表示されているセルを1つのパーツとしてグループ化できます。
Main.storyboard > TableView > Attributes inspector > Style > Grouped
この状態だとTableViewの上部に不要なセル(ヘッダービュー下の灰色のセル)が表示されてしまいます。
これを削除したい場合は、TableViewを設置しているViewController内で下記を追記してください。
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
// Erase header cells
return .leastNormalMagnitude
}
これで見た目も大分すっきりしました。
この他にもTableViewで表現できることはたくさんありますので、興味ある方はぜひ調べてみて下さい。