Luke Lee
Luke Lee

Reputation: 39

Same subview shows repeatedly when custom tableView cell reused (Swift 4.1)

I have a problem when I draw a set of CGRects in my custom tableView cell, they showed repeatedly when the cells get reused, which is not what I desired.

Here is the tableView(cellForRowAt indexPath:) function in my tableView controller:

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

    let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! CustomTableViewCell

    cell.addBlock(item: itemArray[indexPath.row])

    cell.itemTitle.text = itemArray[indexPath.row].itemTitle

    return cell
}

And here is the function in my CustomTableViewCell class: (created with a xib file)

func addBlock(item: Item) {
    for i in 0 ..< item.numberOfBlocks {
        let block = UIView()
        block.frame = CGRect(
            origin: CGPoint(
                x: CGFloat(i) * 10,
                y: 0
            ),
            size: CGSize(
                width: 10,
                height: bounds.size.height
            )
        )
        block.backgroundColor = UIColor.orange
        self.addSubview(block)
    }
}

I think I draw every cell based on the numberOfBlock property in my itemArray Items, but when the cells are reused, the blocks won't redraw... I have tried search here and elsewhere, but I couldn't find the answer (for a long time), I am new to swift, please bear with me...thank you very much.

Note: Item class includes 2 properties: 1. itemTitle: String, 2. numberOfBlocks: Int

Upvotes: 0

Views: 599

Answers (1)

pacification
pacification

Reputation: 6018

I believe you have this problem because let block = UIView() not removed from the cell on reuse. If it is, you can try this strategy:

  1. Hold every let block = UIView() in you CustomTableViewCell class;
  2. Implement prepareForReuse() method and remove all blocks from superview.

This steps guarantee that reused cell doesn't have any block from previous state.

A bit of implementation:

final class CustomTableViewCell: UITableViewCell {

    private var blocks: [UIView] = []

    override func prepareForReuse() {
        super.prepareForReuse()

        blocks.forEach { $0.removeFromSuperview() }
        blocks = []
    }

    func addBlock(item: Item) {
        for ... {
            let block = UIView()
            ...
            blocks.append(block)
        }
    }

}

Upvotes: 1

Related Questions