Select Multiple Rows in Tableview and Tick the Selected Ones

Swift 3.0 multiple selection with select all cell

Create a struct for model data with a Bool property. You can modify this property by cell selection.

simulator

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var allCharacters:[Character] = []

override func viewDidLoad() {
super.viewDidLoad()
allCharacters = [Character(name: "All"),Character(name: "Luke Skywalker"),Character(name: "Leia Organa"),Character(name: "Advik Shah"),Character(name: "Aarav Modi")]

}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return allCharacters.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
if cell == nil{
cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell")
}
cell?.textLabel?.text = allCharacters[indexPath.row].name
if allCharacters[indexPath.row].isSelected
{
cell?.accessoryType = .checkmark
}
else
{
cell?.accessoryType = .none
}
cell?.selectionStyle = .none
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0
{
allCharacters[indexPath.row].isSelected = !allCharacters[indexPath.row].isSelected
for index in allCharacters.indices
{
allCharacters[index].isSelected = allCharacters[indexPath.row].isSelected
}
}
else
{
allCharacters[indexPath.row].isSelected = !allCharacters[indexPath.row].isSelected
if allCharacters.dropFirst().filter({ $0.isSelected }).count == allCharacters.dropFirst().count
{
allCharacters[0].isSelected = true
}
else
{
allCharacters[0].isSelected = false
}
}
tableView.reloadData()
}




}

struct Character
{
var name:String
// var otherDetails
var isSelected:Bool! = false
init(name:String) {
self.name = name
}
}

Creating Array of Struct objects from array of dictionary

let SubjectArray = json["students"] as! [[String:Any]]
allCharacters = SubjectArray.map({ Character(name: $0["studentName"] as! String) })
allCharacters.insert(Character(name:"All"), at: 0)

Add/Remove Multiple Checkmarks on Selected Rows in Swift 4 UITableView

Instead of change accessoryType on didSelectRowAt and didDeselectRowAt methods, you should override and do it on setSelected(_:animated:) from your cell class.

class YourCellClass: UITableViewCell {

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

if selected {
accessoryType = .checkmark
} else {
accessoryType = .none
}
}

}

iOS having issues with UITableView programmatically selecting multiple cells and displaying a check

Override the setSelected method in the custom tableview cell class,

and use tableview.selectRow(at:) function to select cells.

Use tableView.indexPathsForSelectedRows to get selected indexPaths in the table.

Here is a good implementation.
https://github.com/yonat/SelectionList

Reply To New Issue:
Please follow the steps.

  1. viewDidLoad or viewWillAppear method

        var itemsToBeSelected: [String]?
    var listItems: [String]?

    ....
    override func viewDidLoad() {
    super.viewDidLoad()
    if let selected = self.itemsToBeSelected, let listItems = self.listItems {
    selected.forEach { (item) in
    if let index = listItems.index(of: item) {
    let indexPath = IndexPath(item: index, section: 0)
    self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
    }
    }
    }

    self.itemsToBeSelected means they need to be selected by default in the list when the view controller appears. it's just an array of String in the above example.

  2. cellForRowAt method

    No need to call cell.isSelected = true/false or cell.isHighlighted = true/false

    if the cell is a custom cell, you can just apply the content to the cell only. and in the custom cell class, just override setSelected method.

    class ExpansionBayCell {
    ....
    override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
    self.checkBox.isChecked = self.isSelected
    }
    }
  3. when it's time to get all selected values and close the view controller

    func btnDonePressed() {        
    guard let indexPaths = tableView.indexPathsForSelectedRows else {
    btnBackPressed()
    return
    }

    let items = indexPaths.map { self.listItems[$0.row] }
    completion(items)
    btnBackPressed()
    }

Selecting TableView Cell Activates Checkmark in Rows in Multiple Sections

use data store for save checkmarks like this:

var selectedIngredients: Set<IndexPath> = [] // use set for unique save

then didSelect callBack:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
if self.selectedIngredients.contains(indexPath) {
self.selectedIngredients.remove(indexPath)

} else {
self.selectedIngredients.insert(indexPath)
}

self.tableView.reloadData()
}

after reload in CellForRow:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if selectedIngredients.contains(indexPath) {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}

If you want it to have only one Row contain checkmark:

var selectedIngredients: IndexPath? = nil

and didSelect CallBack:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
self.selectedIngredients = indexPath
}

and finally:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if selectedIngredients == indexPath {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}

Single cell Selection in table view in swift

You have to save selected indexes somewhere, may be in some array with different sections. Since you want to have first cells of each section pre-selected lets start with something like this:

   var selectedIndexes = [[IndexPath.init(row: 0, section: 0)], [IndexPath.init(row: 0, section: 1)]]

In above array we are saving two indexpaths. One is for first cell of first section and the second is for first cell of second section.

Now your cellForRow may check for existing indexpaths in the array like so:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as! UITableViewCell
cell.selectionStyle = .none
cell.textLabel?.text = tableArray[indexPath.section][indexPath.row]

let selectedSectionIndexes = self.selectedIndexes[indexPath.section]
if selectedSectionIndexes.contains(indexPath) {
cell.accessoryType = .checkmark
}
else {
cell.accessoryType = .none
}


return cell
}

For single selection:

// For single selection
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)

// If current cell is not present in selectedIndexes
if !self.selectedIndexes[indexPath.section].contains(indexPath) {
// mark it checked
cell?.accessoryType = .checkmark

// Remove any previous selected indexpath
self.selectedIndexes[indexPath.section].removeAll()

// add currently selected indexpath
self.selectedIndexes[indexPath.section].append(indexPath)

tableView.reloadData()
}
}

Above code removes any previously selected cell and saves the new one. If the same cell is selected again and again it remains checked.



Related Topics



Leave a reply



Submit