因此,我正在为UITableView创建一些视图模型。该表具有不同的单元格类型,因此我使用了泛型,但是将它们放入数组时存在一些问题。
首先,我定义了一个结构:
private struct Section<E, C> where C: UITableViewCell {
let cell: C.Type
let rows: [E]
let configure: (_ row: E, _ cell: inout C, _ index: Int) -> Void
}
然后我声明了一个数组:
private lazy var sections: [Any] = [
Section(cell: TextFieldTableViewCell.self,
rows: [
TableRow(image: R.image.home.device.settings.name(),
title: R.string.localizable.deviceSettingsViewControllerElementDeviceName(),
content: device.name,
action: { _ in
}),
TableRow(image: R.image.home.device.settings.location(),
title: R.string.localizable.deviceSettingsViewControllerElementDeviceLocation(),
content: device.location,
action: { _ in
})],
configure: { row, cell, index in
}),
Section(cell: DeviceSettingsNightVisionTableViewCell.self,
rows: [
TableRow(image: R.image.home.device.settings.nightVision(),
title: R.string.localizable.deviceSettingsViewControllerElementNightVision(),
content: 0,
action: { _ in
})],
configure: { row, cell, index in
})
]
问题是:
[Any]
作为数组的类型,那么每次获取元素时,都必须将其转换为对应的类型,这与我的原始设计不一致。我期望的结果是,当我使用一个元素时,无需转换即可正确获取其类型。
我目前的做法是:
在numberOfRowsInSection:
中,
switch section {
case 0:
return (self.sections[section] as! Section<TableRow, TextFieldTableViewCell>).rows.count
case 1:
return (self.sections[section] as! Section<TableRow, DeviceSettingsNightVisionTableViewCell>).rows.count
default:
return 0
}
显然还不够优雅,我想问一下是否有更好的解决方案,任何帮助或建议都将不胜感激。
答案 0 :(得分:0)
您可以为行对象使用协议,并使用标识符代替类型,我不确定这是否可以完全解决您的问题,但是您可以尝试:
protocol CellProtocol where Self: UITableViewCell {
func bind(_ object: RowProtocol)
}
protocol RowProtocol {
}
struct Row1: RowProtocol {
}
struct Row2: RowProtocol {
}
private struct Section {
let cellIdentifier: String
let rows: [RowProtocol]
let configure: (_ row: RowProtocol, _ cell: inout UITableViewCell, _ index: Int) -> Void
}
private lazy var sections: [Section] = [
Section(cellIdentifier: "cell1",
rows: [Row1()],
configure: { row, cell, index in
}),
Section(cellIdentifier: "cell2",
rows: [Row2()],
configure: { row, cell, index in
})
]
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: sections[indexPath.section].cellIdentifier, for: indexPath) as? CellProtocol {
cell.bind(sections[indexPath.section].rows[indexPath.row])
}
}
让您的自定义单元格类符合CellProtocol
,然后在其中的bind
函数中,尝试将RowProtocol
转换为Row1
或Row2
以获得他们的价值观。
我也不确定您将如何在这些sections对象中进行配置,感觉不对,我宁愿让单元类自行处理配置。