0

So, my thought are:

I have different classes of UITableViewCell: CustomCell1, CustomCell2, CustomCell3

I have UITableView, and I need to add them through cellForRowAt, but there can be multiple cell of any type.

For example, table should contain this: CustomCell2, CustomCell2, CustomCell3, CustomCell1, CustomCell1, also there is Bool variable, and if it's true, them CustomCell1 should be added, if not then CustomCell3

Is there any way of creating array of this cell types? Like

arrayOfTypes = [CustomCell2, CustomCell2, CustomCell3, CustomCell1, CustomCell1, boolVariable ? CustomCell1 : CustomCell3]

So then in cellForRowAt I can call like this:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let type = arrayOfTypes[indexPath.row]
        switch type {
        case is CustomCell1:
        ...
        case is CustomCell2:
        ...
        case is CustomCell3:
        ...
        default:
        ...
        }
}

Or maybe there's more convenient way of doing such a thing?

So now in project I do this:

enum CustomCellType {
    case CustomCell1
    case CustomCell2
    case CustomCell3
}

class CellItem {
    var cellType: CustomCellType

    init(CellType type: CustomCellType) {
        self.cellType = type
    }
}

...
class WorkingWithData: UITableViewDataSource, UITableViewDelegate {

    var tableData = [CellItem]()

    override func viewDidLoad() {
        fillCells()
    }

    func fillCells() {
        let cellItem = CellItem(CellType: .CustomCell1)
        tableData.append(cellItem)
        let cellItem2 = CellItem(CellType: .CustomCell3)
        tableData.append(cellItem2)
    }

    ...
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let item = tableData[indexPath.row]
        switch item.cellType {
        case .CustomCell1:
        //dequeuereusablecell
        case .CustomCell2:
        //dequeuereusablecell
        case .CustomCell3:
        //dequeuereusablecell
        default:
        ...
        }
    }
}

Nikita Rysin
  • 29
  • 10
  • Does this answer your question? [UITableview with more than One Custom Cells with Swift](https://stackoverflow.com/questions/30774671/uitableview-with-more-than-one-custom-cells-with-swift) – koen Apr 01 '20 at 12:29

1 Answers1

1

Answer for your first question:

let cellTypes: [UITableViewCell.Type] = [UITableViewCell.self]
    let type = cellTypes[indexPath.row]
    switch type {
    case is UITableViewCell.Type:
        break
    default:
        break
}

Another way:

enum CustomCellType: Int {
    // enum names in swift starts with lower case
    case customCell1
    case customCell2
    case customCell3

    var dequeType: UITableViewCell.Type {
        switch self {
        case .customCell1: return CustomCellType.self
        case .customCell2: return CustomCellType2.self
        case .customCell3: return CustomCellType3.self
        }
    }
}

// Add extension to register and deque cells with type
public extension UITableView {
    func register<T: UITableViewCell>(_ cellType: T.Type) {
        register(cellType, forCellReuseIdentifier: String(describing: cellType))
    }
    func dequeue<T: UITableViewCell>(_ cellType: T.Type, for indexPath: IndexPath) -> T {
        guard let cell = dequeueReusableCell(
            withIdentifier: String(describing: cellType),
            for: indexPath
        ) as? T else {
            fatalError("Unable to dequeue cell for \(cellType)")
        }
        return cell
    }
}

// ––––––––– Inside Class where the tableview exists –––––––––
// Register cells
func registerCells() {
    CustomCellType.allCases.forEach({ tableView.register($0.dequeType) })
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cellType = CustomCellType(rawValue: indexPath.row) else {
        fatalError("Your message")
    }

    let cell = tableView.dequeue(cellType.dequeType, for: indexPath)
    // Cell is now with concrete type
    return cell
}
Samps
  • 799
  • 6
  • 12
  • Samps, i implementer code with let cellTypes: [UITableViewCell.Type] = [UITableViewCell.self] , but it seems, that it doesn't work with custom types of UITableViewCell, because compiler shows me Warning: "Cast from 'UITableViewCell.Type' to unrelated type 'CustomCell1' always fails" in case is CustomCell1: – Nikita Rysin Apr 01 '20 at 13:16
  • You're correct. My bad. You need to use case is UITableViewCell.Type. I fixed in answers also. – Samps Apr 01 '20 at 13:44