はじめに
UITableViewの初期値としてセルにチェックマークを入れるため、コードからセルを選択する必要がありました しかし、次のセルに選択が移った時、初期値に入れておいたチェックマークが外れなかったのです。 ![例1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259778/691308b5-471d-0abd-5678-794d3b62ec29.gif)コードからセルを選択するとセルの解除が呼ばれない
コードからセルを選択をすると、解除のメソッドが呼ばれないようですね deselectRow(at:animated:) や selectRow(at:animated:scrollPosition:) ※ Apple ReferenceCalling this method does not cause the delegate to receive a tableView(_:willDeselectRowAt:) or tableView(_:didDeselectRowAt:) message, nor does it send selectionDidChangeNotification notifications to observers.
対処方法
UITableViewのデリゲートメソッド、[tableView(_:willSelectRowAt:)](https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614943-tableview)に注目して解決しましたUITableViewController.swift
// セルを選択するその直前に呼ばれるメソッド
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
//まだ、この時は次のセルに選択が移っていない、選択中のセルのインデックスパスを取得する。
if let selectedRow = tableView.indexPathForSelectedRow {
tableView.cellForRow(at: selectedRow)?.accessoryType = .none
}
//このindexPathが次に選択されたセルのインデックスパスになる
return indexPath
}
// セルを選択した時に呼ばれるメソッド
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
willSelectRowAtの中では、まだ次のセルにインデックスパスが移っていないため、
tableView.indexPathForSelectedRowにて取得ができる。
ということで、コードで選択した場合であっても選択していたセルのインデックスパスが取得できました。