-1

i am adding multiple selection in tableview with sections in tableview, so how can i store that section index as well as indexpath of that cell for display when user click on cell inside that particular sections that will store in array as selected item and reflect in cellForRowAtindexpath the better solution is appreciated

func numberOfSections(in tableView: UITableView) -> Int {
    return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return itemsInSections[section].count
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return self.sections.count;
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    let header = view as! UITableViewHeaderFooterView
    header.textLabel?.textColor = UIColor(red: 8/255, green: 38/255, blue: 76/255, alpha: 1.0)
    header.backgroundColor = UIColor.clear

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tablheaders.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
    let section = indexPath.section
    if checkdarray.count > 0
    {
        if (self.checkdarray[section][indexPath.row] as Int == 1)
        {
            cell.accessoryType = .checkmark;
        }
        else
        {
            cell.accessoryType = .none;
        }
    }

    cell.textLabel?.text = itemsInSections[indexPath.section][indexPath.row] as! String

    return cell

}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
     let section = indexPath.section as Int
    let indepaths = indexPath.row as Int
    tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark
    checkdarray.insert([1], at: [section][indepaths])
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none
   // checkdarray.remove(at: indexPath.row)

    //checkdarray.insert(0, at: indexPath.row)
}
ronit
  • 37
  • 12
  • I would use a `Set` and then just insert/remove the index path as required. You then use `contains` in `cellForRow(at:)` – Paulw11 Apr 05 '19 at 11:03
  • you mean just using indexpath for selected item store in array and get in cellForRow(at:) compare that array item with indexpath.row @Dávid Pásztor – ronit Apr 05 '19 at 11:05
  • Don't store it in an array, store it in a `Set` – Paulw11 Apr 05 '19 at 11:08
  • do you have any example for quick understand ? @Paulw11 – ronit Apr 05 '19 at 11:12
  • @Paulw11 Why Set is preferred over Array? – RajeshKumar R Apr 05 '19 at 11:12
  • `var selected = Set()`. `selected.insert(indexPath)`. A set is preferred because you can efficiently determine if the set contains an item and you don't need to worry about indicies – Paulw11 Apr 05 '19 at 11:14
  • @all who are suggesting an index path set: **Don’t use separate collections to save data which actually belongs to the model**. That’s very bad practice. At the latest if cells can be moved you are in trouble. Add the `isSelected` information to the data model. When the selection changes update the model and reload the row. – vadian Apr 05 '19 at 11:51
  • Short example would be great to understand your model update @vadian – ronit Apr 05 '19 at 12:06

2 Answers2

0
I have used button in table...
// declare var
 var checkarrMenu = Set<IndexPath>()

// In tableView
 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return array.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = mManageTableView.dequeueReusableCell(withIdentifier: "TableViewCellID")as! TableViewCell
        cell.mRadioBtnAct.tag = indexPath.row
        cell.mRadioBtnAct.addTarget(self, action: #selector(mRadioCheck(sender:)), for: .touchUpInside)
        if checkarrMenu.contains(indexPath){
            cell.mradioimage.image = UIImage(named: "Radiochecked")
        }else{
            cell.mradioimage.image = UIImage(named: "Radio checkedlightRadio3")
        }
        return cell
    }
// on radio btn Action
 @objc func mRadioCheck(sender:UIButton){
        let touchPoint: CGPoint = sender.convert(CGPoint.zero, to: mManageTableView)
        // maintable --> replace your tableview name
        let clickedButtonIndexPath = mManageTableView.indexPathForRow(at: touchPoint)
        if checkarrMenu.contains(clickedButtonIndexPath){
            checkarrMenu.remove(clickedButtonIndexPath)

        }else{
            checkarrMenu.insert(clickedButtonIndexPath)

            }
        tableView.reloadData()
       }
// hope its works for you!
Paulw11
  • 108,386
  • 14
  • 159
  • 186
Sukh
  • 1,278
  • 11
  • 19
  • Don't use `NSMutableArray` in Swift unless necessary for Objective C interoperability – Paulw11 Apr 05 '19 at 11:23
  • okk then i will use set of indexPath Set() , answer updated – Sukh Apr 05 '19 at 11:32
  • @Paulw11 so what we can use instead of this NSMutableArray, it seems like he is storing button position which is pretty like indexpath row, i tried his code and i get result like below output of that array -> ( " {length = 2, path = 0 - 0}"), ( " {length = 2, path = 1 - 0}") – ronit Apr 05 '19 at 11:38
0

The most efficient and reliable solution is to keep the isSelected state in the data model.

Use a struct as data model and add a member isSelected along with the other information you need.

struct Model {
    var isSelected = false
    var someOtherMember : String

    // other declarations
}

In cellForRow set the checkmark according to the isSelected member

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) // use always the passed tableView instance

    let model = itemsInSections[indexPath.section][indexPath.row]
    cell.accessoryType = model.isSelected ? .checkmark : .none
    cell.textLabel?.text = model.someOtherMember

    return cell

}

In didSelectRowAt and didDeselectRowAt update the model and reload the row

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    itemsInSections[indexPath.section][indexPath.row].isSelected = true
    tableView.reloadRows(at: [indexPath], with: .none)
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    itemsInSections[indexPath.section][indexPath.row].isSelected = false
    tableView.reloadRows(at: [indexPath], with: .none)
}

Never use an extra array to save index paths. Don't do that.

vadian
  • 274,689
  • 30
  • 353
  • 361