【Swift】UITableViewCellの特定のセルを選択不可にする

2021.10.21

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

男には誰だって 「うちの可愛いTableViewCellは誰にも選択させたくない」 という時が人生で一度や二度あるかと思います。

私もちょうどその時期がやってきまして、特定のUITableVIewCellを選択できなくする方法を調べましたので書き記しておきたいと思います。

開発環境

  • Xcode 13
  • Swift 5.5

まずこんな動きをするアプリです

画面の中央下にTableViewがあり、didSelectRowAtでは選択されたセルの絵文字が画面上部にあるラベルに反映されるようになっています。

// Table view delegate - did select row at
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    currentEmojiLabel.text = cellItems[indexPath.row].emoji
}

これからこの一番上のセルに選択不可の処理を追加したいと思います。

選択不可の処理を実装

UITableViewにはselectionStyleというプロパティがあるのですがこちらを.noneにすると選択不可になる?

cell.selectionStyle = .none

と思っていたのですが、

自分の勘違いでselectionStyle.noneを設定すると選択時にセルの背景色に変化がない(選択されていないようにみえる)だけで、タップされた箇所のdidSelectRowAtの処理は実行されているので選択後の処理は実行されていることになります。

selectionStyleの公式ドキュメントを読んでみると、

selection styleはセルのbackgroundViewの定数で、選択された時のセルのカラーを決定します。 デフォルト値は.blueです。 使える定数についてはUITableViewCell.SelectionStyleを見てね。

という書いてあり、

cell.selectionStyle = .noneでは選択された時のセルの色を未設定にしているだけなのですね。

どうりで処理は実行されるわけだ。

次こそ選択不可の処理の実装

これで選択不可の処理が行えます。

cell.isUserInteractionEnabled = false

isUserInteractionEnableUIViewのプロパティでfalseを設定することでViewが行うとしているタッチやキーボードやフォーカスイベントなどを無視して、イベントキューを削除してくれます

isUserInteractionEnablefalseに設定するとデフォルトでラベルの色が不活性を表すような薄いグレーになりました。

もし、選択不可中でも色を別の色に変更したい場合は、セルのテキストカラーを設定するだけで変更できます。

// Table view data source - cell for row at
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    // UserInteractionEnabledを設定
    cell.isUserInteractionEnabled = indexPath.row != 0

    var configuration = cell.defaultContentConfiguration()
    // テキストを設定
    configuration.text = cellItems[indexPath.row].emojiWithMessage
    // テキストカラーを設定
    configuration.textProperties.color = .black
    cell.contentConfiguration = configuration

    return cell
}

これで無事に特定のセルを選択させない実装ができました。お疲れ様でした?‍♂️

これであなたの大事なセルを選択させないで済みますね!

TableViewCellのことを引き続きよろしくお願いいたします。