【问题标题】:Reload a table view's data without clearing its selection state重新加载表视图的数据而不清除其选择状态
【发布时间】:2013-10-30 15:44:24
【问题描述】:

我有一个带有可选行的表格视图。 当我重新加载表格视图时,可能会添加(或删除)一些新行,并且表格视图单元格中的一些标签可能会更改。这就是我想通过调用[tableView reloadData] 来实现的目标。

不幸的是,该方法还清除了表格视图的整个状态 - 包括选择。但我需要保留选择。

那么如何在表格视图中重新加载所有数据,同时仍然保持选中的行?

【问题讨论】:

    标签: ios uitableview reloaddata


    【解决方案1】:

    您可以使用以下方式存储所选行的索引路径:

    rowToSelect = [yourTableView indexPathForSelectedRow];
    

    在重新加载数据之前。并在重新加载使用后:

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

    【讨论】:

      【解决方案2】:

      JeroVallis 解决方案适用于单一选择表视图。 根据他的想法,这就是我如何使其适用于多项选择:

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

      【讨论】:

      • 但这将为每个先前选择的单元格再次调用 DidselectRowAtIndexPath。当用户选择一个单元格时,将触发我编写的操作。
      【解决方案3】:

      具有一些优势的替代方法是仅重新加载尚未选择的行。 Swift 代码如下。

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

      【讨论】:

        【解决方案4】:

        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)
            })
        }
        

        【讨论】:

        • 这是 a 方式,但不是 正确方式。为数据模型中的每个单元格保持 selected 状态效率更高。
        • 每个 UITableViewCell 子类已经有每个单元格的“isSelected”属性。认为您需要在不重新加载表格视图的情况下更改所需单元格的选定状态。您不能通过在数据模型中保持选定状态来归档此目的。所以在我看来,使用预定义的 isSelected 属性更正确。
        • 是的,你可以。 viewisSelected 属性应该反映modelisSelected 属性的状态,反之亦然。直接操作视图是非常糟糕的习惯和低效。
        • 如果您将选定状态保存在数据模型中,则必须重新加载整个或特定(行/部分)表以更改单元格的选定视图。你说“是的,我们可以”。你能发给我一个无需重新加载即可更改选定单元格视图的代码 sn-p 吗?
        • 当然你必须重新加载这个(一个)特定的行。但这比获取所有选定的单元格要高效得多,创建一个新变量来保存数据,重新加载 整个 表视图并重新分配每个单元格的选定状态循环。
        【解决方案5】:

        最有效的方法是在数据模型中保持selected状态

        • 在表示数据源的结构或类中添加布尔属性isSelected
        • cellForRowAt中根据属性设置单元格的选中状态。
        • didSelectRow 在数据源项中切换isSelected 并仅重新加载给定索引路径处的特定行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-02-24
          • 2017-09-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-22
          相关资源
          最近更新 更多