はじめに
「TableViewControllerを配置しただけだと、何か質素なデザインになってしまう。」「セルとセルの空間をもっと空けたい。」こんな時、あると思います。ここではUITableViewCell
を継承したクラスを作成し、好みのカスタムセルを作成する方法を共有します。「こうした方がいい!」と感じた場合はコメントで教えて欲しいです。
こんな感じのTableViewができます。(上にNavigationBarがありますが。)
作り方
UITableViewCellを継承したクラスを作成する
class CustomTableViewCell: UITableViewCell {
}
初期化の処理をかく
セルの色や文字の場所などのセットアップを行う関数を行うための場所というイメージです。
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
元々のViewを透明にする処理
ここではカスタムビューを表現する方法として、UITableViewCell
が元々持っているUIView(contentView
という)とは別のUIViewを用意し、そのUIViewに色をつけるなどしています。なのでcontentView
を透明にし、見えないようにします。
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
contentView.backgroundColor = .clear
backgroundColor = .clear
}//追加した
}
contentView
そのものをいじりカスタムセルを作成する方法がありそうですが、技術不足により実装できませんでした。ここら辺のコメント特に募集しています。
UIViewを用意し、準備する
ここからはコードベースでレイアウトを組むときにやっていることとあまり変わりません。私の過去の記事でもコードベースでレイアウトを組むことについて書いているので、もし詰まったら参考にして下さい。
private let backView = UIView()
private func setupUIView() {
backView.backgroundColor = UIColor(255,189,40)
backView.layer.cornerRadius = 5
addSubview(backView)
backView.snp.makeConstraints {
$0.width.equalToSuperview().multipliedBy(0.8)
$0.height.equalTo(contentView.snp.height).multipliedBy(0.9)
$0.center.equalToSuperview()
}
}
留意点及びやっていることとしては
- レイアウトが楽になるライブラリSnapKitを使っている
- セルの高さが
contentView
の0.9倍になるようにしている - セルの幅が画面サイズの0.8倍になるようにしている
- 角丸をつけている
です。
テキストが表示できるようにUILabelを用意する
セルを表示するだけであれば上述したことだけでOKなのですが、表示させる物が一つは必要なのでUILabel
を追加します。
let titleLabel = UILabel()
private func setupcellLabel() {
titleLabel.font = UIFont.systemFont(ofSize: 20)
backView.addSubview(titleLabel)
titleLabel.snp.makeConstraints {
$0.centerX.equalToSuperview().offset(30)
$0.centerY.equalToSuperview()
$0.width.equalToSuperview()
}
}
セルから少し右に離れたところにテキストが表示されるようにしています。
セットアップ関数をイニシャライザにいれる
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUIView()
setupcellLabel()
}
ここまでで一応それっぽく動かすための準備はできました。一旦ここまでのソースコードを載せます。
import UIKit
class CustomTableViewCell: UITableViewCell {
private let backView = UIView()
let titleLabel = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUIView()
setupcellLabel()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUIView() {
backView.backgroundColor = UIColor(255,189,40)
backView.layer.cornerRadius = 5
addSubview(backView)
backView.snp.makeConstraints {
$0.width.equalToSuperview().multipliedBy(0.8)
$0.height.equalTo(contentView.snp.height).multipliedBy(0.9)
$0.center.equalToSuperview()
}
}
private func setupcellLabel() {
titleLabel.font = UIFont.systemFont(ofSize: 20)
backView.addSubview(titleLabel)
titleLabel.snp.makeConstraints {
$0.centerX.equalToSuperview().offset(30)
$0.centerY.equalToSuperview()
$0.width.equalToSuperview()
}
}
override func layoutSubviews() {
contentView.backgroundColor = .clear
backgroundColor = .clear
}
}
contentViewのハイライトをなくす
上の通り動かすと、contentView
がハイライト処理を行ってしまうため、セルを選択したときにしたの画像のようになってしまいます。
これは良くない🙃
まずはハイライト消します。
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUIView()
setupcellLabel()
self.selectionStyle = .none//追加した
}
次にセルが選択された際に先ほど自分で定義したUIView
がハイライト処理されるようにします。
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: true)
backView.backgroundColor = selected ? UIColor(255,226,146) : UIColor(255,189,40)
}
backView
の背景色をセルが選択された時は少し明るめの色、そうでない時は元々の色となるようにします。
三項間演算子を使っていますが、全然if文でも書けます。
完成! あとはTabeViewControllerでこのクラスを使うだけです。
TableViewでの処理
UITableViewDataSource
の関数で以下のように書きます。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell//いつもと違う
return cell
}
あとはregister
のところで
register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")
のように書けば先ほど作ったカスタムセルを使うことができます。