[Xcode/Swift] UITableViewCellを知る

UITableViewCellは、iOSアプリ開発においてリスト形式でデータを表示するための重要な要素です。UITableViewは、複数の行を含むリストビューを提供し、その各行はUITableViewCellによって表されます。この記事では、UITableViewCellの基本的な使い方からカスタムセルの作成方法まで、サンプルコードを交えて解説します。

UITableViewCellの基本

UITableViewCellは、テーブルビューの各行を表すビューです。デフォルトで提供されるスタイルもあり、ラベルや画像を表示するためのUI要素が組み込まれています。セルは再利用可能で、スクロールパフォーマンスを最適化するために再利用キューを使用します。

主なプロパティ

  • textLabel: セルの主なテキストを表示するラベル。
  • detailTextLabel: 補足テキストを表示するラベル。
  • imageView: セルの左側に表示される画像。
  • accessoryType: セルの右側に表示されるアクセサリ(チェックマーク、詳細ボタンなど)。

UITableViewCellのスタイルと再利用

UITableViewCellは、デフォルトで4つのスタイルが提供されています。それぞれが異なるレイアウトとUI要素を持っています。

スタイル例:

  • default: テキストラベル(textLabel)のみ。
  • subtitle: テキストラベルとサブタイトルラベル(detailTextLabel)。
  • value1: テキストラベルと右揃えの詳細ラベル。
  • value2: 左揃えの詳細ラベルと右揃えのテキストラベル。
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
cell.textLabel?.text = "タイトル"
cell.detailTextLabel?.text = "サブタイトル"

デフォルトのUITableViewCellの使用

シンプルなリスト表示では、デフォルトのUITableViewCellを再利用して使うのが効率的です。以下のコードは、標準的なセルを使ったテーブルビューのセットアップです。

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    let tableView = UITableView()

    let data = ["Apple", "Banana", "Cherry", "Date", "Elderberry"]

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.frame = view.bounds
        tableView.dataSource = self
        tableView.delegate = self
        view.addSubview(tableView)
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
        cell.textLabel?.text = data[indexPath.row]
        return cell
    }
}

カスタムUITableViewCellの作成

より複雑なUIを持つセルが必要な場合は、カスタムUITableViewCellを作成します。カスタムセルでは、デフォルトのラベルや画像以外のUIコンポーネントを自由に配置できます。

カスタムセルの例

1: 新しいクラスを作成

import UIKit

class CustomTableViewCell: UITableViewCell {
    let customImageView = UIImageView()
    let customLabel = UILabel()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupViews()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupViews() {
        customImageView.translatesAutoresizingMaskIntoConstraints = false
        customLabel.translatesAutoresizingMaskIntoConstraints = false

        contentView.addSubview(customImageView)
        contentView.addSubview(customLabel)

        NSLayoutConstraint.activate([
            customImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
            customImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            customImageView.widthAnchor.constraint(equalToConstant: 40),
            customImageView.heightAnchor.constraint(equalToConstant: 40),

            customLabel.leadingAnchor.constraint(equalTo: customImageView.trailingAnchor, constant: 10),
            customLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
            customLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
        ])
    }

    func configure(with image: UIImage?, text: String) {
        customImageView.image = image
        customLabel.text = text
    }
}

2: TableViewで使用

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "customCell")
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as? CustomTableViewCell else {
        return UITableViewCell()
    }
    cell.configure(with: UIImage(named: "exampleImage"), text: "カスタムセルのテキスト")
    return cell
}

UITableViewCellのアクションとインタラクション

UITableViewCellは、標準的なインタラクション(タップ、スワイプなど)に対応しています。また、スワイプアクションやアクセサリボタンなどを追加して、ユーザーの操作を簡単に処理できます。

スワイプアクションの追加:

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(style: .destructive, title: "削除") { (action, view, completionHandler) in
        // 削除処理
        completionHandler(true)
    }
    return UISwipeActionsConfiguration(actions: [deleteAction])
}

セルの動的高さの設定

セルの内容に応じて高さを動的に変更する場合は、オートレイアウトを使用します。また、UITableViewrowHeightプロパティをUITableView.automaticDimensionに設定します。

tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 44.0

UITableViewCellのベストプラクティス

  • 再利用を徹底する: dequeueReusableCellを使用して、セルを再利用することでメモリ使用量を最適化します。
  • オートレイアウトを活用する: 動的コンテンツに対応するため、オートレイアウトを活用してセルのレイアウトを柔軟に保ちます。
  • セルの分離: カスタムセルは独自のファイルに分け、メンテナンス性を向上させましょう。

まとめ

UITableViewCellは、iOSアプリにおけるリスト表示の基本を支える重要なコンポーネントです。デフォルトのスタイルからカスタムセルまで、多様なニーズに対応するための柔軟な設計が可能です。この記事を参考に、UITableViewCellを使いこなして、ユーザーにとって使いやすいインターフェースを作りましょう。