繁体   English   中英

在数组中快速移动不同类型的泛型

[英]Swift different types of generics in array

因此,我正在为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
    })
  ]

问题是:

  1. 我无法指定数组的类型,因为它们实际上是不同的泛型。
  2. 如果我使用[Any]作为数组的类型,那么每次使用元素时,都必须将其转换为对应的类型,这与我的原始设计不一致。
  3. 我进行了一些搜索,意识到可能需要使用协议来解决问题,但是我尝试了很多次却失败了。

我期望的结果是,当我使用一个元素时,无需转换即可正确获取其类型。

我当前的方法是:

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
        }

显然这还不够优雅,我想问一下是否有更好的解决方案,非常感谢您的帮助或建议。

您可以为行对象使用协议,并使用标识符代替类型,我不确定这是否可以完全解决您的问题,但是您可以尝试:

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功能,尝试将转换RowProtocolRow1Row2 ,以得到他们的价值观。

而且我不确定您将如何在该sections对象内进行配置,感觉很不好,我宁愿让单元类自行处理配置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM