F Matheus
F Matheus

Reputation: 25

Why my Tableview is reusing some cells?

I have a Todo list, i have a label and a button in the same cell, when i click the button, change the image button for that cell, but when i scrolled the table view the same button appears on the others cells, it was not to appear in cells that the button were not pressed.

Here is my cellForRowAtIndexPath code

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! TaskTableViewCell


    cell.label.text = "Task Number: \(indexPath.row + 1)"
    cell.btnFavorite.setImage(UIImage(named: "star"), forState: .Normal)
    cell.btnFavorite.setImage(UIImage(named: "star-filled"), forState: .Selected)
    cell.btnFavorite.addTarget(self, action: #selector(ListOfTasksViewController.addRemoveFavoriteList), forControlEvents: .TouchUpInside)


    return cell
}

func addRemoveFavoriteList(sender : UIButton) {
    sender.selected = !sender.selected

}

Custom TableViewCell Class:

 import UIKit

class TaskTableViewCell: UITableViewCell {

    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var btnFavorite: FavoriteButton!

    override func awakeFromNib() {
        super.awakeFromNib()

    }

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

    }

    override func prepareForReuse() {
        super.prepareForReuse()
        label.text = nil
        btnFavorite.selected = false

    }

}

View Controller:

import UIKit

class ListOfTasksViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! TaskTableViewCell


        cell.label.text = "Task Number: \(indexPath.row + 1)"

        cell.btnFavorite.indexPath = indexPath.row

        cell.btnFavorite.addTarget(self, action: #selector(ListOfTasksViewController.addRemoveFavoriteList), forControlEvents: .TouchUpInside)


        return cell
    }

    func addRemoveFavoriteList(sender : FavoriteButton) {

        if sender.selected {
            sender.selected = false


        } else {
            sender.selected = true

            let index = NSIndexPath(forRow: sender.indexPath, inSection: 0)
            let cell = tableView.cellForRowAtIndexPath(index) as! TaskTableViewCell


        }

    }




}

Upvotes: 0

Views: 94

Answers (2)

KKRocks
KKRocks

Reputation: 8322

you need to add condition in the cellforaRowAtIndexPath.

you need to add flag in Array which track your selection. then its check in cellforRowAtIndexPath.

for example

button.selected= No

if arrselectedIndexpath containObject:indexPath{
button.selected =yes
}

Upvotes: 0

Callam
Callam

Reputation: 11539

The cells in your table view are reused so as you scroll down, the cells going off screen are being put at the start of the queue before going back onto the screen at a different indexPath. This can cause some issues so you need to override the prepareForReuse method in your custom cell class.

override func prepareForReuse() {

    super.prepareForReuse()

    label.text = nil
    btnFavorite.selected = false
}

Upvotes: 2

Related Questions