Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select multiple rows in tableview and tick the selected ones

Tags:

swift

I'm loading a tableView from a plist file. This works with no problems. I just simply want to "tick" the selected rows. At the moment, with my code it didn't work as desired. At the moment, it looks as below:

  • tap row1 (it will tick row 1 = good)
  • tap row1 again (nothing happens = bad. I expect here the row to be unticked) While tapping again on row 1, it unticks then. After the second tap on it.
  • when I tap row0 at the initial load of the tableview it never ticks me the row

my code:

class portals: UITableViewController {

    var lastSelectedIndexPath = NSIndexPath(forRow: -1, inSection: 0)

...

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! UITableViewCell

        // Configure the cell...
        cell.textLabel!.text = portals[indexPath.row]

        return cell
    }


    // Check which portal is selected
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        var whichPortalIsSelected: String = ""

        // Get Cell Label
        let indexPath = tableView.indexPathForSelectedRow();

        // Tick the selected row
        if indexPath!.row != lastSelectedIndexPath?.row {

            let newCell = tableView.cellForRowAtIndexPath(indexPath!)
            newCell?.accessoryType = .Checkmark

            lastSelectedIndexPath = indexPath

            whichPortalIsSelected = newCell!.textLabel!.text!
            println("You selected cell #\(lastSelectedIndexPath.row)!") //PPP
            println("You selected portal #\(whichPortalIsSelected)!") //PPP

        // Un-Tick unselected row
        } else {
            let newCell = tableView.cellForRowAtIndexPath(indexPath!)
            newCell?.accessoryType = .None

            whichPortalIsSelected = newCell!.textLabel!.text!
            println("You unselected cell #\(indexPath!.row)!") //PPP
            println("You unselected portal #\(whichPortalIsSelected)!") //PPP
        }

    }
}
like image 588
tefter Avatar asked May 28 '15 20:05

tefter


People also ask

How do you get the IndexPath row when a button in a cell is tapped?

add an 'indexPath` property to the custom table cell. initialize it in cellForRowAtIndexPath. move the tap handler from the view controller to the cell implementation. use the delegation pattern to notify the view controller about the tap event, passing the index path.

What is IndexPath in tableView Swift?

Swift version: 5.6. Index paths describe an item's position inside a table view or collection view, storing both its section and its position inside that section.


4 Answers

Swift 4

First, make your tableView support multiple selection :

self.tableView.allowsMultipleSelection = true
self.tableView.allowsMultipleSelectionDuringEditing = true

Then simply subclass UITableViewCell like this :

class CheckableTableViewCell: UITableViewCell {
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.selectionStyle = .none
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        self.accessoryType = selected ? .checkmark : .none
    }
}

Finally, use it in your cellForRowAt indexPath as such :

let cell = tableView.dequeueReusableCell(withIdentifier: "cell", 
    for: indexPath) as? CheckableTableViewCell

If you have to, don't forget to subclass your prototype cell in your xib/storyboard : enter image description here

like image 73
Alexandre G. Avatar answered Oct 19 '22 04:10

Alexandre G.


First of all, go to your Storyboard and select you tableview and in the Attributes Inspector, set Selection to Multiple Selection.

Attributes Inspector with multiple selection

Then, override the setSelected(_ selected: Bool, animated: Bool) function in the subclass of UITableViewCell.

override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        accessoryType = selected ? UITableViewCellAccessoryType.checkmark : UITableViewCellAccessoryType.none
    }
like image 22
Aatish Rajkarnikar Avatar answered Oct 19 '22 04:10

Aatish Rajkarnikar


This enable untick.

class TableViewController: UITableViewController
{
    var lastSelectedIndexPath = NSIndexPath(forRow: -1, inSection: 0)

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) 

        // Configure the cell...
        cell.textLabel!.text = "row: \(indexPath.row)"

        if cell.selected
        {
            cell.selected = false
            if cell.accessoryType == UITableViewCellAccessoryType.None
            {
                cell.accessoryType = UITableViewCellAccessoryType.Checkmark
            }
            else
            {
                cell.accessoryType = UITableViewCellAccessoryType.None
            }
        }

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
        let cell = tableView.cellForRowAtIndexPath(indexPath)

        if cell!.selected
        {
            cell!.selected = false
            if cell!.accessoryType == UITableViewCellAccessoryType.None
            {
                cell!.accessoryType = UITableViewCellAccessoryType.Checkmark
            }
            else
            {
                cell!.accessoryType = UITableViewCellAccessoryType.None
            }
        }
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return 100
    }
}
like image 11
Liew Tze Hau Avatar answered Oct 19 '22 05:10

Liew Tze Hau


you have to make a costume class to get the selected state of the cell where you must override a func called setSelected(_ selected: Bool, animated: Bool) or the tick will be displayed randomly as you scroll ... here is an example of what i did: 1- created a class for the cell 2- added an outlet for an image to display the tick (you can escape this if you don't want a costume tick image) 3- overrided the function and used the param selected :D

here is my class:

import UIKit

class AddLocationCell: UITableViewCell {

     @IBOutlet weak var check: UIImageView!

        override func awakeFromNib() {
            super.awakeFromNib()
            // Initialization code
        }

        override func setSelected(_ selected: Bool, animated: Bool) {
            super.setSelected(selected, animated: animated)
            if selected{
                check.image = UIImage(named:"check_active")
            }else{
                check.image = UIImage(named:"check_normal")

            }
            // Configure the view for the selected state
        }
}
like image 5
mohammad alnajjar Avatar answered Oct 19 '22 03:10

mohammad alnajjar