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.
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.
viewDidLoad
orviewWillAppear
methodvar 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 ofString
in the above example.cellForRowAt
methodNo need to call
cell.isSelected = true/false
orcell.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
}
}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
Which Format File for 3D Model Scenekit/Arkit Better to Use
Differencebetween Swift 2.0 Do-Try-Catch and Regular Java/C#/C++ Exceptions
Passing Data from Tableview to Viewcontroller in Swift
Moving Node on Top of a Moving Platform
Swift Setting Badge Value for Uitabbaritem
What's the Difference Between If Nil != Optional … and If Let _ = Optional …
How to Create a Window with Transparent Background with Swift on Osx
How Does Dictionary Use the Equatable Protocol in Swift
Cast a Swift Struct to Unsafemutablepointer<Void>
Swiftier Swift for 'Add to Array, or Create If Not There...'
Swift Dictionary: Remove Time Complexity
Scene Size in Xcode 6/Spritekit/Swift
Why to Avoid Forced Unwrapping
How to Play Multiple Audio Files Simultaneously Using Avplayer
How to Retrieve a Random Object from Firebase Using a Sequential Id