【发布时间】:2013-11-26 12:18:58
【问题描述】:
通常我将数据存储在一个数组中。然后,当调用 cellForRowAtIndexPath 时,我只需查看行并根据行和进程选择数组上的一个项目。
但是我们知道的 UITableView 可以做组视图。
那我该怎么办?
我应该有一个数组数组吗?数组的 NSDictionary?在 UITableView 结构中存储数据最优雅的方式是什么?
【问题讨论】:
通常我将数据存储在一个数组中。然后,当调用 cellForRowAtIndexPath 时,我只需查看行并根据行和进程选择数组上的一个项目。
但是我们知道的 UITableView 可以做组视图。
那我该怎么办?
我应该有一个数组数组吗?数组的 NSDictionary?在 UITableView 结构中存储数据最优雅的方式是什么?
【问题讨论】:
例如一个字典数组,其中每个字典包含 标题和一个部分的所有项目:
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];
所有其他数据源方法也很容易实现。
【讨论】:
@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]
【讨论】:
我喜欢 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()
}
编码愉快!如果需要进一步阐述或有任何错误,请在评论中告诉我。
【讨论】: