きっかけ
仕事で他の人のソースをみることはよくありますが、最近UITableViewでセルの再利用をしていないソースを3回みました。
え?まじ??いいの???私老人会なのかしらって思いました。
iPhoneもだいぶハードが進化していろんなむちゃぶりされても動くようにはなってきたのですが、ちゃんとかいたほうがぬるぬる綺麗にうごくんじゃない?って思うんです。それで、まとめることにしました。
そういえば、cellForRowAtでcellの中身を全部removefromSuperviewしてから、addSubviewするというコードも1年ぐらい前に見たことがあります。
xib絶対使わない派の人もいるとは思いますが、楽したいなら使っちゃいましょう。
基本の考え方
1.中に表示するUITableViewCellは再利用する作りにする
- TableViewにregisterして、使うときにはdequeueReusableCellを使って再利用する
2.cellForRowAt でセルを生成するときの処理は、極力最小になるように努力する
- CALayerを使った角丸の処理は遅い
- 画像をネット経由で読み込む場合には非同期に読み込む
3.heightForRowAtも頻繁に呼ばれるので注意する
- cellの高さの計算が必要なら、cellそのものを使うのではなく、計算用の別クラスを使う
やりかた1.Storyboard内のTableView内でCellのプロトタイプを書いてしまう
いいところ
- registerしなくてもいい
- ファイルが増えないのでプロジェクトがスッキリする
あんまよくないところ
- 他の画面でも同じセルを使い回すときにめんどうかもしれない
手順
2.オブジェクトライブラリからTableViewCellをTableViewに貼り付ける
3.セルの高さを変えたり、なかに必要なオブジェクトを貼り付けてカスタマイズする
5.セルのクラスを作成する
import UIKit
class SampleCell1:UITableViewCell {
@IBOutlet weak var sampleImageView: UIImageView!
@IBOutlet weak var sampleLabel:UILabel!
@IBOutlet weak var sampleSwitch:UISwitch!
@IBOutlet weak var sampleIndicator:UIActivityIndicatorView!
}}
6.Storyboardに戻ってTableViewCellを選択してクラス名を5で作ったクラス名にする
7.Identifierに、呼び出すためのユニークな文字列を入れる
8.TableViewCellのところが自分で作ったクラスになるのでアウトレットを結ぶ
9.TableViewで直接プロトタイピングしているので7でつけた名前でそのままViewControllerから呼び出せます
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SampleCell1") as! SampleCell1
return cell
}
やりかた2.XIBに別ファイルとして出してそれを使う
いいところ
- 他のビューでも同じようなセルを使いまわしたいときによい
- xibとswiftがペアで格納できるので、ロジックを追いやすい
あんまよくないところ
- registerを忘れてできない!!ってハマることがある
やり方
1.セルのXibを作る
3.1のXibでTableViewCellを選択してクラス名を2で作ったクラスにする
5.ViewControllerのviewDidLoadで作ったクラスのレジストレーションをする
今回はUIViewにUITableViewを貼り付けたのでOutletで結んでself.tableViewとなっています。
あとidentifierは定数にしましょう
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.register(UINib(nibName: "SampleCell2", bundle: nil), forCellReuseIdentifier: "SampleCell2")
}
6.あとはそのままViewControllerから呼び出せます
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SampleCell2") as! SampleCell2
return cell
}