Generi c UITableview Cell - PullRequest
       5

Generi c UITableview Cell

0 голосов
/ 20 апреля 2020

Я хочу создать табличное представление с таможенными ячейками, каждая ячейка отличается. Но я хочу, чтобы реализация была такой умной. Я подумал, вместо того, чтобы делать, если еще проверить cellForRow:atIndex: для каждой ячейки, подобной этой

if indexpath.section == 0 {
  // Create first cell
} else if indexpath.section == 1 {
  // Create second cell
}

и т. Д.

Я решил создать протокол следующим образом:

protocol tableviewProtocol {
  func cellForAt(index: IndexPath, object: ObjectModel) -> UItableviewCell
}

и для каждой ячейки, которую я хочу показать, я создаю класс следующим образом:

class firstCellClass: tableviewProtocol {
    func cellForAt(index: IndexPath, object: ObjectModel) -> UItableviewCell {
       // create and return the cell
    }
}

и создал этот массив,

var tableviewDataSource: [tableviewProtocol] = []

, а затем заполнил массив следующим образом :

tabletableviewDataSource = [firstCellClass(), secondCellClass(), thirdCellClass()]

и в tableView cellForRow:atIndex:

return tableviewDataSource[indexpath.section].cellForAt(indexpath, object: object)

И это было хорошо, пока мне не пришлось создавать другую ячейку с другим типом объектной модели вместо ObjectModel

Так, как я могу сделать его более обобщенным c, который может принимать любые типы объектов?

Ответы [ 3 ]

0 голосов
/ 21 апреля 2020

Я понимаю, что это не самый элегантный способ сделать это, но, надеюсь, он вам поможет.

Допустим, у вас есть три типа:

struct ModelA { ... }
struct ModelB { ... }
struct ModelC { ... }

Таким образом, вы можете создать массив типа Any:

var model = [[Any]]() // append data

Затем в cellForRow:

var cell: UITableViewCell

let value = model[indexPath.section][indexPath.row]

switch val {
case is ModelA:
    cell = tableView.dequeueReusableCell(withIdentifier: "cellA", for: indexPath) as! CellClassA
case is ModelB:
    cell = tableView.dequeueReusableCell(withIdentifier: "cellB", for: indexPath) as! CellClassB
case is ModelC:
    cell = tableView.dequeueReusableCell(withIdentifier: "cellC", for: indexPath) as! CellClassC
default:
    cell = UITableViewCell()
}

return cell

0 голосов
/ 21 апреля 2020

У Nighttalker был хороший ответ, чтобы просто использовать «Любой», но вы также можете попробовать 2 других способа:

  1. Сделать ObjectModel протоколом и сделать все объекты, которые вы хотите передать в реализации. этот протокол

    protocol ObjectModel{
    
    }
    
    class SomeObject: ObjectModel{}
    
  2. Используйте дженерики

    protocol tableviewProtocol {
        associatedtype ObjectModel
        func cellForAt(index: IndexPath, object: ObjectModel) -> UITableViewCell      
     }
    
    class SomeObject: tableviewProtocol{
    
         typealias ObjectModel = String //whatever type you want
    
         func cellForAt(index: IndexPath, object: ObjectModel) -> UITableViewCell{
        //return your cell
         }
    
     }
    
0 голосов
/ 20 апреля 2020

Вы можете сделать его более обобщенным c, создав подкласс UITableViewCell

class firstCellClass: UITableViewCell {

}

class secondCellClass: UITableViewCell {

}

class thirdCellClass: UITableViewCell {

}


let arrayOfCells = [UITableViewCell]()

Что-то подобное должно указать вам правильное направление. Есть много способов достичь этой цели

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...