简体   繁体   中英

my table view reuse the selected cells when scroll — in SWIFT

Good Morning

my problem is that my table view reuse the selected cell when i scroll down and up again .. i mean when i select one cell from up then scroll down, some cells which i didnt select are shown selected, also some selected cells from up are not showed selected when i scroll up again, and when that happened i am apple again to select more than just one cell which must be not allowed .. i want to mention that i tried to save the old index path from 'didSelectRowAtIndexPath'and i checked it like this in the 'CellForRowAtIndexPath'but it doesnt work :

if (old == indexpath)
{
        cell?.backgroundColor = UIColor.redColor()
        cell?.textLabel?.backgroundColor = UIColor.whiteColor() //to change only the thumbnail color and keep the cell color 
}

else {
        cell?.backgroundColor = UIColor.whiteColor()
}

Now here is my code

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = myTable.dequeueReusableCellWithIdentifier("WorkCell") as UITableViewCell
    cell.tag = (indexPath.row) + 1
    cell.textLabel?.text = Berufs[indexPath.row]
    var img = UIImageView(frame: CGRect(x: 10, y: 3, width: 40 , height: 40))
    cell.selectionStyle = UITableViewCellSelectionStyle.None
    img.image = UIImage(named: "transparent.png")
    cell.indentationLevel = 1
    cell.indentationWidth = 45
    cell.addSubview(img)
    return cell
}

var old = 1000

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
    let indexPath = tableView.indexPathForSelectedRow()
    let cell = tableView.cellForRowAtIndexPath(indexPath!)
    var tmpCell = view.viewWithTag(old)
    var rowNum = (cell?.tag)! - 1

    if (cell?.backgroundColor == UIColor.redColor())
    {
        cell?.backgroundColor = UIColor.whiteColor()
    }
    else if (cell?.backgroundColor != UIColor.redColor())
    {
        tmpCell?.backgroundColor = UIColor.whiteColor()
        cell?.backgroundColor = UIColor.redColor()
        cell?.textLabel?.backgroundColor = UIColor.whiteColor()

        println("du interssiert dich für \(Berufs[rowNum])")
    }

    old = rowNum + 1

}

You currently store the selection state in the backgroundColor. That's not a good idea because for performance reasons cells will be reused by the tableView.

You should save the selected indexPaths in the data model. If you want to allow multiple selection you can store the selected indexPaths in a NSMutableSet.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    cell.selectionStyle = .None
    configure(cell, forRowAtIndexPath: indexPath)
    return cell
}

var selectedIndexPaths = NSMutableSet()

func configure(cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.textLabel!.text = "Row \(indexPath.row)"
    if selectedIndexPaths.containsObject(indexPath) {
        // selected
        cell.backgroundColor = UIColor.redColor()
    }
    else {
        // not selected
        cell.backgroundColor = UIColor.whiteColor()
    }
}


override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if selectedIndexPaths.containsObject(indexPath) {
        // deselect
        selectedIndexPaths.removeObject(indexPath)
    }
    else {
        // select
        selectedIndexPaths.addObject(indexPath)
    }
    let cell = tableView.cellForRowAtIndexPath(indexPath)!
    configure(cell, forRowAtIndexPath: indexPath)
}

If you only need single selection you should save the selected indexPath in an NSIndexPath? instance variable

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    cell.selectionStyle = .None
    configure(cell, forRowAtIndexPath: indexPath)
    return cell
}

var selectedIndexPath: NSIndexPath?

func configure(cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.textLabel!.text = "Row \(indexPath.row)"
    if selectedIndexPath == indexPath {
        // selected
        cell.backgroundColor = UIColor.redColor()
    }
    else {
        // not selected
        cell.backgroundColor = UIColor.whiteColor()
    }
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if selectedIndexPath == indexPath {
        // selected same cell -> deselect all
        selectedIndexPath = nil
    }
    else {
        // select different cell
        let oldSelectedIndexPath = selectedIndexPath
        selectedIndexPath = indexPath

        // refresh old cell to clear old selection indicators
        var previousSelectedCell: UITableViewCell?
        if let previousSelectedIndexPath = oldSelectedIndexPath {
            if let previousSelectedCell = tableView.cellForRowAtIndexPath(previousSelectedIndexPath) {
                configure(previousSelectedCell, forRowAtIndexPath: previousSelectedIndexPath)
            }
        }
    }
    let selectedCell = tableView.cellForRowAtIndexPath(indexPath)!
    configure(selectedCell, forRowAtIndexPath: indexPath)
}

I had the same problem a while ago, what I did is, I added a new variable (Bool) named isset to the CustomTableViewCell, and when I created the cell for the first time, I changed it to true, so after I wanted to reuse an already set cell, I just returned the arleady set one, to not set is again:

let cell = tableView.dequeueReusableCellWithIdentifier("Cellidentifier", forIndexPath: indexPath) as CustomTableViewCell

if cell.isset
{
        return cell
}

//set your cell here 
cell.isset = true
return cell

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM