skip to Main Content

I have a tableview cells, and the titles I get from server. Titles are array of strings. The data is drawing like this

  • All data
  • List item
  • Coffees
  • Teas
  • Dessert
  • Main dishes

when I click on each of these I can easily select them and deselect, that part works perfect. Now i want that when i select List item, Coffees, teas, dessert, main dishes together, these 5 items will be deselected and all data(first cell) will be selected automatically.
I know i should write this in didselect method, only i dont know how to write logic correctly. Please help me to solve this. Thanks

this is my code example

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let isSelected = arrayOfTitles[indexPath.row].isSelected else {arrayOfTitles[indexPath.row].isSelected = true; return}
        arrayOfTitles[indexPath.row].isSelected = !isSelected
        filter?.values?[indexPath.row].isSelected = !isSelected
        for i in 1..<arrayOfTitles.count {
            if arrayOfTitles[i].isSelected == isSelected {
                arrayOfTitles[0].isSelected = isSelected
                arrayOfTitles[i].isSelected = !isSelected
            }
        }
    }

2

Answers


  1. You can try

    
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            guard let isSelected = arrayOfTitles[indexPath.row].isSelected else {arrayOfTitles[indexPath.row].isSelected = true; return}
            arrayOfTitles[indexPath.row].isSelected = !isSelected
            filter?.values?[indexPath.row].isSelected = !isSelected
            let allSelected = arrayOfTitles[1...].filter { $0.isSelected }
            if allSelected.count == arrayOfTitles.count - 1 {
               arrayOfTitles[0].isSelected = true
                (1..<arrayOfTitles.count).forEach { arrayOfTitles[$0].isSelected = false }
            }
    }
    
    Login or Signup to reply.
  2. Because a table view maintains its own array of selected rows (IndexPaths), you don’t really need to maintain a separate .isSelected property on your data. If you need it (for state persistence, for example), you can always grab the selected rows when needed.

    So, here’s another approach…

    I’m guessing that if you have some of the rows selected, and you then select the top row, you would also want to deselect the other rows:

    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
        
        var arrayOfTitles: [String] = [
            "All data",
            "List Item",
            "Coffees",
            "Teas",
            "Dessert",
            "Main dishes",
        ]
        
        let tableView = UITableView()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            tableView.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(tableView)
            
            let g = view.safeAreaLayoutGuide
            NSLayoutConstraint.activate([
                tableView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
                tableView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
                tableView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
                tableView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -20.0),
            ])
            
            tableView.register(UITableViewCell.self, forCellReuseIdentifier: "c")
            tableView.dataSource = self
            tableView.delegate = self
            
            tableView.allowsMultipleSelection = true
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return arrayOfTitles.count
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let c = tableView.dequeueReusableCell(withIdentifier: "c", for: indexPath)
            c.textLabel?.text = arrayOfTitles[indexPath.row]
            return c
        }
        
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            // ignore if nothing is selected
            guard let paths = tableView.indexPathsForSelectedRows else { return }
            
            // if we selected the top row ("All data"), deselect the others
            if indexPath.row == 0 {
                // deselect the other rows
                paths.forEach {
                    if $0.row != 0 {
                        tableView.deselectRow(at: $0, animated: true)
                    }
                }
            } else {
                // get the selected rows as a sorted array of Int
                let rows: [Int] = (paths.map { $0.row }).sorted()
                // Int array of rows 1 thru 5
                let myFiveRows: [Int] = Array(1...5)
                // if the two arrays are equal (they're both [1,2,3,4,5])
                if rows == myFiveRows {
                    // deselect all
                    tableView.selectRow(at: nil, animated: true, scrollPosition: .none)
                    // select the top row
                    tableView.selectRow(at: IndexPath(row: 0, section: 0), animated: true, scrollPosition: .none)
                }
            }
        }
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search