0

I'm trying to handle the dequeue reusable cell for my situation. I'm not sure I'm doing things the best way here, I was able to handle the weird stuff about dequeueing the cells for the text labels in my custom cells. I handled that with override func prepareForReuse() in the cell xib code. However when I try to handle the cell background in the same way it does not work as its supposed to. I believe this is because I'm changing cell background elsewhere than the tableView function...

So the problem is the cell background isn't changing as its supposed to, typical dequeue reusable cell issues. If I put backgroundColor = nil inside prepareForReuse() then the background does not show at all. If I leave it out then the background color jumps all over the tableView when I scroll.

FYI I have registered the cells properly in viewDidLoad()

I think this is enough code to explain the situation. Appreciate any pointers :)

Mark cell background RED

func markRED(cell: EntrantCell) {
    var timeOut: String {
        let currentDateTime = Date()
        let formatter = DateFormatter()
        formatter.timeStyle = .medium
        return formatter.string(from: currentDateTime)
    }
    if let indexPath = self.entrantsTable.returnIndexPath(cell: cell) {
        entryStatusGrid[indexPath.row] = 2
        entrantTime[indexPath.row].append("OUT- \(timeOut)")
        entrantsTable.cellForRow(at: indexPath)?.backgroundColor = #colorLiteral(red: 0.7647058964, green: 0.01910983652, blue: 0.008289327978, alpha: 1)
        entrantsTable.reloadData()
    }
    print(entrantTime)
    print(entryStatusGrid)
    
    // TODO: Handle proper space status for global button
    Entrant.updateStatus(entryStatusGrid: entryStatusGrid, button: spaceStatus)
}

TableView extension

extension EntrySession: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return entryGrid.count
}

// TODO: Handle proper deque for reusable cells
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    let addEntrantCell = entrantsTable.dequeueReusableCell(withIdentifier: Global.headerCellIdentifier, for: indexPath) as! AddEntrantCell
    let entrantCell = entrantsTable.dequeueReusableCell(withIdentifier: Global.bodyCellIdentifier, for: indexPath) as! EntrantCell
    
    if indexPath.row == 0 {
        
        addEntrantCell.delegate = self
        addEntrantCell.entrantNameTextField.text = entryGrid[indexPath.row].name
        addEntrantCell.entrantCompanyTextField.text = entryGrid[indexPath.row].company
        return addEntrantCell
    } else {
        
        entrantCell.delegate = self
        entrantCell.nameLabel.text = entryGrid[indexPath.row].name
        entrantCell.companyLabel.text = entryGrid[indexPath.row].company
        return entrantCell
    }
}
}

Custom cell reuse()

override func prepareForReuse() {
    super.prepareForReuse()
    name.text = nil
    status.text = nil
    backgroundColor = nil         // When i do this the background color does not change...
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
}

@IBAction func inButton(_ sender: UIButton) {
    delegate?.markRED(cell: self)
}
@IBAction func outButton(_ sender: UIButton) {
    delegate?.markBLUE(cell: self)
}
RobbB
  • 1,214
  • 11
  • 39

1 Answers1

1

You need to always set it — to what's appropriate.

if shouldSetBackgroundColor {
    backgroundColor = .brown
} else {
    backgroundColor = nil
}

Let's assume you initialize only 4 cells. Then show 4 cells. Assume all have shouldSetBackgroundColor set to true. As a result you see all 4 cell's backgroundColor to brown. So far so good.

Now comes your 5th cell. If you don't set shouldSetBackgroundColor to false on the cell or don't have some logic to change the color of the backgroundColor then because the cell gets re-used, the backgroundColor won't change. It will remain set to brown...

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • Thanks for the input Honey, but I'm a bit of a noob. Where exactly should this if statement be inserted? And the "shoudSetBackgroundColor", should that be a global boolean variable set by my protocol method markRED? – RobbB Jan 04 '21 at 23:12
  • Good question. Inside your `cellForRowAtIndex`. For more on `cellForRowAtIndex` vs. `prepareForReuse` see [here](https://stackoverflow.com/questions/40773208/what-is-the-correct-way-to-use-prepareforreuse/47514477#47514477). The idea is that anytime you want to setup the cell, you have to assume that all characteristics of the cell are not what you want (because they were set by the previous cell that used them but is no off the screen). Hence the need for you to set it again – mfaani Jan 05 '21 at 00:00
  • I was afraid I would have to put that into `cellForRowAtIndex`. But this is good, this definitely helps my knowledge of tableView. And good resource too. Thank you – RobbB Jan 05 '21 at 00:50