I like this pattern enabled by Swift:
let sections = [(title: "Alpha", rows: ["A", "B", "C"]),
(title: "Numeric", rows: ["1", "2", "3"])]()
Then in cell for row at index path:
let data = sections[indexPath.section].rows[indexPath.row]
Thanks to Martin R's answer for inspiration. My actual implementation uses another pattern that I have to use disparate cell classes and data types like this:
protocol BaseViewModel {
var cellIdentifier: String
}
class BaseCell: UITableViewCell {
func setupWith(viewModel: BaseViewModel) {}
}
class SpecificCell: BaseCell {
override func setupWith(viewModel: BaseViewModel {
if let viewModel = viewModel as? SpecificCellViewModel {
// set properties from object conforming to my vm protocol
}
}
}
Implementation:
let sections: [(title: String, rows: [BaseViewModel])]
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let viewModel = sections[indexPath.section].rows[indexPath.row]
let cell = let tableCell = tableView.dequeueReusableCell(withIdentifier: viewModel.cellIdentifier , for: indexPath) as? BaseTableViewCell
tableCell?.setupWith(viewModel: viewModel)
return tableCell ?? UITableViewCell()
}
Happy coding! Let me know with a comment if this needs further elaboration or has any errors.