web-dev-qa-db-ja.com

選択状態をクリアせずにテーブルビューのデータをリロードします

選択可能な行を含むテーブルビューがあります。テーブルビューをリロードすると、いくつかの新しい行が追加(または削除)され、テーブルビューのセルの一部のラベルが変更される場合があります。それが私が[tableView reloadData]を呼び出すことによって達成したいことです。

残念ながら、そのメソッドは、選択を含むテーブルビューの状態全体もクリアします。しかし、私は選択を維持する必要があります。

では、選択した行を選択したまま、テーブルビューのすべてのデータを再読み込みするにはどうすればよいですか?

18
Mischa

選択した行のインデックスパスは、次の方法で保存できます。

rowToSelect = [yourTableView indexPathForSelectedRow];

データをリロードする前。そしてリロード使用後:

[yourTableView selectRowAtIndexPath:rowToSelect animated:YES scrollPosition:UITableViewScrollPositionNone];
22
JeroValli

JeroVallisソリューションは、単一選択テーブルビューで機能します。彼の考えに基づいて、これは私が複数の選択でそれを機能させる方法です:

NSArray *selectedIndexPaths = [self.tableView indexPathsForSelectedRows];
[tableView reloadData];
for (int i = 0; i < [selectedIndexPaths count]; i++) {
    [tableView selectRowAtIndexPath:selectedIndexPaths[i] animated:NO scrollPosition:UITableViewScrollPositionNone];
}
11
Mischa

最も効率的な方法は、データモデルでselected状態を維持することです。

  • データソースを表す構造体またはクラスにブールプロパティisSelectedを追加します。
  • cellForRowAtで、プロパティに従ってセルの選択された状態を設定します。
  • didSelectRowでデータソースアイテムのisSelectedを切り替え、指定されたインデックスパスの特定の行のみを再読み込みします。
3
vadian

いくつかの利点がある代替手段は、選択されていない行のみをリロードすることです。 Swift以下のコード。

        if var visibleRows = tableView.indexPathsForVisibleRows,
            let indexPathIndex = visibleRows.index(of: indexPath) {
            visibleRows.remove(at: indexPathIndex)
            tableView.reloadRows(at: visibleRows, with: .none)
        }
0
Justin Domnitz

Swift 4.2テスト済み

テーブルビューのリロード後に選択した行を更新する正しい方法は次のとおりです。

// Saves selected rows
let selectredRows = tableView.indexPathsForSelectedRows

tableView.reloadData()

// Select row after table view finished reload data on the main thread
DispatchQueue.main.async {
    selectredRows?.forEach({ (selectedRow) in
        tableView.selectRow(at: selectedRow, animated: false, scrollPosition: .none)
    })
}
0
muhasturk