Swift 3.0 Multiple Selection with Select All Cell

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)

swift 3.0 multiple selection with Select All option

Jayprakash, You are almost there. You need to modify some lines -

Here is your modified code snippet

var unchecked:Bool = true

@IBAction func btnCheckBoxClick(_ sender: Any) {

if(unchecked){

unchecked = false
}
else{

unchecked = true
}

ObjTableview.reloadData()

}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

if(indexPath.row == 0){

btnCheckBoxClick(sender: UIButton())

}

}

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

let cell : SelectUserCell!
cell = tableView .dequeueReusableCell(withIdentifier: "SelectUserCell", for: indexPath) as! SelectUserCell
cell.selectionStyle = UITableViewCellSelectionStyle.none

if(unchecked){

cell.btnCheckbox.setImage(UIImage(named: "unSelectedItem"), for: .normal)

}
else{

cell.btnCheckbox.setImage(UIImage(named: "selectedItem"), for: .normal)
}

// Do your stuff here

return cell
}

Hop it will simplify your code structure.

Swift: Multiple TableView checkmark - select all rows

You have to check if the user selected the first row ("Select all") and update the other rows accordingly:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// toggle the selected area
areas[indexPath.row].isSelected.toggle()

// save the new state for later use
let isSelected = areas[indexPath.row].isSelected

if indexPath.row == 0 {
// "Select all" was selected – update all areas
for i in 1..<areas.count {
areas[i].isSelected = isSelected
}

// update UI
tableView.visibleCells.forEach { $0.accessoryType = isSelected ? .checkmark : .none }
} else {
// update UI
tableView.cellForRow(at: indexPath)?.accessoryType = isSelected ? .checkmark : .none
}

tableView.deselectRow(at: indexPath, animated: true)
}

Recommendation

To separate concerns visually you could also use an own table view section for the "Select all" row. In that case some more changes are necessary:

var areas = [
// you do not need an area for "Select all" any longer
Area(name: "a"),
Area(name: "b"),
Area(name: "c"),
Area(name: "d")
]

var allSelected: Bool {
// helper var to see if all areas are currently selected
return areas.filter({!$0.isSelected}).isEmpty
}

override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 1: return "Areas"
default: return nil
}
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0: return 1 // select all
case 1: return areas.count
default:
// we should never get here
fatalError()
}
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.selectionStyle = .none

if indexPath.section == 0 {
cell.textLabel?.text = "Select all"
cell.accessoryType = allSelected ? .checkmark : .none
} else {
let area = areas[indexPath.row]
cell.textLabel?.text = area.name
cell.accessoryType = area.isSelected ? .checkmark : .none
}

return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
// (de-)select all
let shouldSelect = !allSelected
for i in 0..<areas.count {
areas[i].isSelected = shouldSelect
}
} else {
areas[indexPath.row].isSelected.toggle()
}

tableView.reloadRows(at: tableView.indexPathsForVisibleRows ?? [], with: .automatic)
}

Swift make select/unselect in single/multiple selection mode for UICollectionView inside UITableViewCell

try this and let me know if you have any problem or if this solved your problem.


var arrSelectedIndex:[IndexPath] = []// store this array either in database by api or in local
var clvData:[String] = []// your data array

//get the arrSelectedIndex from default in viewDidLoad before reloading the table and collection.
override func viewDidLoad() {
super.viewDidLoad()
if let myArray = UserDefaults.standard.array(forKey: "selectedArray") as? [IndexPath] {
arrSelectedIndex = myArray
} else {
arrSelectedIndex = []
}
}

// and save the arrSelectedIndex in viewWillDisappear method
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
UserDefaults.standard.set(arrSelectedIndex, forKey: "selectedArray")
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return clvData.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "clvCell", for: indexPath) as! demoCollectionViewCell
cell.title.text = clvData[indexPath.item] as? String

if arrSelectedIndex.contains(indexPath) { // You need to check wether selected index array contain current index if yes then change the color
cell.backgroundColor = UIColor.red
}
else {
cell.backgroundColor = UIColor.white
}

return cell

}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = .red
if !arrSelectedIndex.contains(indexPath) {// if it does not contains the index then add it
arrSelectedIndex.append(indexPath)
}
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.backgroundColor = .white
if let currIndex = arrSelectedIndex.firstIndex(of: indexPath) {// if it contains the index then delete from array
arrSelectedIndex.remove(at: currIndex)
}
}

How to get the label values from multiple selected cells in a UITableView and pass them to a different ViewController swift

Override the prepare(for segue: UIStoryboardSegue, sender: Any?) in the AddContactsListTableView class where you can pass the selected contacts to the next view controller.

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Pass the selected object to the new view controller.
if let selectedRows = tableView.indexPathsForSelectedRows {
let selectedContacts = selectedRows.map{contacts[$0.row]}
let newVC = segue.destination as! NewViewController
newVC.contacts = selectedContacts
}
}

See this tutorial for more.



Related Topics



Leave a reply



Submit