簡體   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