soranoba
soranoba Author of soranoba.net
programming

iOS15でUITableViewCell.isHiddenを使ってはいけない

iOS15/Xcode13に対応する季節になりました.
一般的に必要な対応についてはマネーフォワードの方が記事を公開しているので改めて触れる必要はないでしょう. (調べる手間が省けて大変助かりました)

ここでは殆どの人が踏み抜かないであろうiOS15で変わった点を紹介したいと思います.

UITableViewCell.isHiddenの値を変更できない場合がある

結論から言うと, 特定の場合にUITableViewCell.isHiddenの値の変更ができなくなりました.
これはiOS15 + Xcode13という条件で発生するもので, Xcode12でビルドした場合やiOS14で実行した場合などでは同様の問題は発生しません.

UITableViewCell.isHiddenを使う一般的な場面はないと思いますが, 設定画面などの表示したい内容が基本的に固定されているが, 一部のCellが条件によって表示されなくなる場合にこれを使用していました.

class ViewController: UITableViewController {
    private var allCells: [UITableViewCell] = []
    private var currentCells: [UITableViewCell] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        allCells = (0..<100).map { _ in UITableViewCell(style: .default, reuseIdentifier: nil) }
        reload()
        // 省略
    }

    private func reload() {
        currentCells = allCells.filter { !$0.isHidden }
        tableView.reloadData()
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return currentCells[indexPath.row]
    }
}

allCellsが全ての表示する可能性があるCellで, currentCellsが現在表示しなければならないCellです.
更新する必要がある時に, allCellsから表示するべきではないhiddenなCellを除外し, currentCellsに代入するといった形になっています.
(実際に使っているのは, セクション対応や初期化の利便性を高めたもので実装は異なります)

iOS15 + Xcode13では, 1度UITableViewに表示したCellを非表示 (isHidden = false)にした後, 表示 (isHidden = true)することができなくなりました.
表示前の操作に関しては可能なので, 上記のような管理をしない限りは影響しないと思われます.


この記事の挙動は以下のレポジトリから確認することができます.

  • https://github.com/soranoba/iOS-SandBox/tree/iOS15_Donot_use_UITableViewCell_isHidden

(Updated: )

comments powered by Disqus