0

I created two different cells to show different data in them. And I assigned reuseIdentifier ("TableCell" and "FixtureCell") to them. They have two different classes named FixtureTableViewCell and LeagueTableViewCell

I want to do that if the cell identifier is "TableCell" show TableCell.

Else if the cell identifier is "FixtureCell", show FixtureCell.

How can I do this control?

My code is as below. I did only "TableCell". I couldn't do for the other one.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tblLeagueTable.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! LeagueTableViewCell

    let teams = tableArray[indexPath.row]

    cell.lblLeagueTableTeam.text! = teams.teamName
    cell.lblOwnGoal.text! = teams.ownGoal
    cell.lblScoredGoal.text! = teams.scoredGoal
    cell.lblLeagueTableTotalMatch.text! = teams.totalMatch
    cell.lblTotalPoints.text! = teams.totalPoint

    return cell
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131

4 Answers4

1

According to previous experience, based on IndexPath to implement dynamic style isn't a good idea. I would like to suggest the model-driven plan.

First, define a model like this:

class DemoCellModel: NSObject {
    var identifier: String = ""
    var classTypeString: String?
    var cellData: NSObject?

    convenience init(identifier: String, classTypeString: String? = nil, cellData: NSObject? = nil) {
        self.init()
        self.identifier = identifier
        self.classTypeString = classTypeString
        self.cellData = cellData
    }
}

and then, create a model array:

var models: [DemoCellModel]  = []

override func viewDidLoad() {
    super.viewDidLoad()
    guard var bundleName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String else { return }
    bundleName = bundleName + "."
    models.append(DemoCellModel(identifier: "TableCell", classTypeString: bundleName + "LeagueTableViewCell", cellData: nil))
    models.append(DemoCellModel(identifier: "FixtureCell", classTypeString: bundleName + "FixtureTableViewCell", cellData: nil))
}

finally, generate your custom cell:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return models.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let model = models[indexPath.row]
    var cell = tableView.dequeueReusableCell(withIdentifier: model.identifier)
    if cell == nil {
        var cellClassType: UITableViewCell.Type
        if let classTypeString = model.classTypeString, let classType = (NSClassFromString(classTypeString) as? UITableViewCell.Type) {
            cellClassType = classType
        } else {
            cellClassType = UITableViewCell.self
        }
        cell = cellClassType.init(style: .default, reuseIdentifier: model.identifier)
    }

    if var cell = cell as? testProtocol {
        cell.cellData = model.cellData
    }

    return cell!
}

protocol testProtocol {
   var cellData: NSObject? { get set }
}
Kyle Wang
  • 48
  • 7
0

Based on the indexPath you decide the suitable cell to display, so your code should look something like this:

var cell: UITableViewCell?
if isTableViewCell(indexPath) {

    cell = tblLeagueTable.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! LeagueTableViewCell

    let teams = tableArray[indexPath.row]

    cell.lblLeagueTableTeam.text! = teams.teamName
    cell.lblOwnGoal.text! = teams.ownGoal
    cell.lblScoredGoal.text! = teams.scoredGoal
    cell.lblLeagueTableTotalMatch.text! = teams.totalMatch
    cell.lblTotalPoints.text! = teams.totalPoint

    } else {

    cell = tblLeagueTable.dequeueReusableCell(withIdentifier: "FixtureCell", for: indexPath) as! FixtureTableViewCell

    // Customize your FixtureCell here
}
Mo Abdul-Hameed
  • 6,030
  • 2
  • 23
  • 36
0

My cells implement a CListTableViewCellProtocol where there is only a config:

protocol CListTableViewCellProtocol {
    mutating func config(data: MyData, callback: @escaping (_ value: Double) -> Void)
}

I have encapsulated all the specific stuff in functions and then it goes straightforward:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cellIdentifier = getCellStyleForSection(indexPath.section).cellIdentifier()

    var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CListTableViewCellProtocol

    cell.config(data:getDataFromIndexPath(indexPath),
        callback: {
            (value: Double) -> Void in
            self.setCValue(indexPath: indexPath, value: value))
        }
    )

    return cell as! UITableViewCell
}


/// And a function to register the cells
func registerCells(tableView: UITableView) -> Void {

    self.tableView = tableView

    tableView.register(CListTableViewCell.self,
                       forCellReuseIdentifier: CCellStyle.editable.cellIdentifier())
    tableView.register(CListTableViewCellSmall.self,
                       forCellReuseIdentifier: CCellStyle.small.cellIdentifier())

}

And CCellStyle is just an enum:

enum CCellStyle:String {
    case small = "CellSmall"
    case editable = "CellEditable"

    func height() -> Int {
        switch self {
        case .small:
            return 20
        case .editable:
            return 36
        }
    }

    func cellIdentifier() -> String {
        return self.rawValue
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
muescha
  • 1,544
  • 2
  • 12
  • 22
0

Try this:

Use a different identifier as the table section. You can also use index.row.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let identifier: String = "TableCell"
    let fixtureIdentifier: String = "FixtureCell"
    var cell: UITableViewCell?
    cell = tableView.dequeueReusableCell(withIdentifier: indexPath.section == 0 ? identifier : fixtureIdentifier)
    if cell == nil {
        cell = UITableViewCell(style: .default, reuseIdentifier: indexPath.section == 0 ? identifier : fixtureIdentifier)
    }
    if indexPath.section == 0 {
       // Do code for TableCell
    }
    else if indexPath.section == 1 {
       // Do code for FixtureCell
    }
    return cell!
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
KKRocks
  • 8,222
  • 1
  • 18
  • 84