【问题标题】:What would be a good data structure for UITableView in grouped mode分组模式下 UITableView 的良好数据结构是什么
【发布时间】:2013-11-26 12:18:58
【问题描述】:

通常我将数据存储在一个数组中。然后,当调用 cellForRowAtIndexPath 时,我只需查看行并根据行和进程选择数组上的一个项目。

但是我们知道的 UITableView 可以做组视图。

那我该怎么办?

我应该有一个数组数组吗?数组的 NSDictionary?在 UITableView 结构中存储数据最优雅的方式是什么?

【问题讨论】:

    标签: objective-c uitableview


    【解决方案1】:

    例如一个字典数组,其中每个字典包含 标题和一个部分的所有项目:

    NSArray *dataSource = @[
                        @{@"title": @"Section 0",
                          @"rows" : @[ item00, item01, item02] },
                        @{@"title": @"Section 1",
                          @"rows" : @[ item10, item11, item12] },
                        @{@"title": @"Section 2",
                          @"rows" : @[ item20, item21, item22] },
                        ];
    

    项目可以是字符串或自定义类的对象。那么你就可以 访问cellForRowAtIndexPath中的每个项目像

    Item *item = dataSource[indexPath.section][@"rows"][indexPath.row];
    

    所有其他数据源方法也很容易实现。

    【讨论】:

    • 太棒了。我也是这么想的。
    • 这是一个很好的方法。它有助于保持所有与 UITableView 相关的代码干净且易于管理。
    【解决方案2】:

    @Martin 的答案对于 Objective-C 是正确的,但在 Swift 中,我们没有为字典提供变量 types 的奢侈。类型是预定义的。

    我们需要使用struct 或自定义数据类型来解决。

    struct Model<Item>{
      let title: String
      let rows: [Item]
    
      subscript(index: String) -> [Item] {
        get {
          return rows
        }
      }
    }
    
    let model1 = Model(title: "Secton 0", rows: ["A", "B", "C"])
    let model2 = Model(title: "Secton 1", rows: ["D", "E", "F"])
    
    let dataSource = [model1, model2]
    
    // You can query
    dataSource[indexPath.section][rows][indexPath.row]
    

    【讨论】:

      【解决方案3】:

      我喜欢 Swift 启用的这种模式:

      let sections = [(title: "Alpha", rows: ["A", "B", "C"]),
                     (title: "Numeric", rows: ["1", "2", "3"])]()
      

      然后在索引路径处的行的单元格中:

      let data = sections[indexPath.section].rows[indexPath.row]
      

      感谢 Martin R 的回答提供灵感。我的实际实现使用了另一种模式,我必须使用不同的单元类和数据类型,如下所示:

      protocol BaseViewModel {
          var cellIdentifier: String
      }
      
      class BaseCell: UITableViewCell {
          func setupWith(viewModel: BaseViewModel) {}
      }
      
      class SpecificCell: BaseCell {
          override func setupWith(viewModel: BaseViewModel {
              if let viewModel = viewModel as? SpecificCellViewModel {
                  // set properties from object conforming to my vm protocol
              }
          }
      }
      

      实施:

      let sections: [(title: String, rows: [BaseViewModel])]
      
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          let viewModel = sections[indexPath.section].rows[indexPath.row]
          let cell = let tableCell = tableView.dequeueReusableCell(withIdentifier: viewModel.cellIdentifier , for: indexPath) as? BaseTableViewCell
          tableCell?.setupWith(viewModel: viewModel)
      
          return tableCell ?? UITableViewCell()
      }
      

      编码愉快!如果需要进一步阐述或有任何错误,请在评论中告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-05
        • 2018-06-18
        • 2012-10-30
        • 1970-01-01
        • 2011-11-23
        • 1970-01-01
        • 2012-02-03
        • 1970-01-01
        相关资源
        最近更新 更多