3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

コードベースでカスタムTableViewCellを作る

Last updated at Posted at 2021-01-22

はじめに

「TableViewControllerを配置しただけだと、何か質素なデザインになってしまう。」「セルとセルの空間をもっと空けたい。」こんな時、あると思います。ここではUITableViewCellを継承したクラスを作成し、好みのカスタムセルを作成する方法を共有します。「こうした方がいい!」と感じた場合はコメントで教えて欲しいです。

Simulator Screen Shot - iPhone 11 Pro Max - 2021-01-22 at 13.25.29.png
こんな感じの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がハイライト処理を行ってしまうため、セルを選択したときにしたの画像のようになってしまいます。
スクリーンショット 2021-01-22 14.09.34.jpg

これは良くない🙃
まずはハイライト消します。

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")

のように書けば先ほど作ったカスタムセルを使うことができます。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?