Nitesh Nitesh - 4 months ago 16
Swift Question

SELECT Tableview cell as per result from API

How to pass previous selected cell by its string. From API i'm getting result by "|" separated, then i'm putting it back into array after removing the separator. But how to pass the result into the tableview which will have selected tableview cell as per result.

This is dummy copy of how i'm doing the selection and saving the result into an array.

class TableViewController: UITableViewController
{
let limit = 5
var lastSelectedIndexPath = NSIndexPath(forRow: -1, inSection: 0)
var genreList = ["A","B","C","D","E","F","G","H"]
var stringRepresentation = String()
var result = [String]()
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)

// Configure the cell...
cell.textLabel!.text = genreList[indexPath.row]

if cell.selected
{
cell.accessoryType = UITableViewCellAccessoryType.Checkmark
}
else
{
cell.accessoryType = UITableViewCellAccessoryType.None
}
return cell
}


override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
if let sr = tableView.indexPathsForSelectedRows {
if sr.count == limit {
let alertController = UIAlertController(title: "Oops", message:
"You are limited to \(limit) selections", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: {action in
}))
self.presentViewController(alertController, animated: true, completion: nil)

return nil
}

}

return indexPath
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
print("selected \(genreList[indexPath.row])")

let cell = tableView.cellForRowAtIndexPath(indexPath)

if cell!.selected == true
{
cell!.accessoryType = UITableViewCellAccessoryType.Checkmark
result.append((cell?.textLabel?.text)!)
print(result)
}
else
{

cell!.accessoryType = UITableViewCellAccessoryType.None
print(result)
}
}


override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {

let deselectedCell = tableView.cellForRowAtIndexPath(indexPath)

result = result.filter { $0 != deselectedCell?.textLabel?.text }

stringRepresentation = result.joinWithSeparator("|") // "1-2-3"

print(stringRepresentation)

deselectedCell!.accessoryType = UITableViewCellAccessoryType.None

}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return genreList.count
}

}

Answer

Try to select cell like this way, use your result array for that

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)

    // Configure the cell...
    cell.textLabel!.text = genreList[indexPath.row]
    if result.contains(genreList[indexPath.row])
    {
        cell.accessoryType = UITableViewCellAccessoryType.Checkmark
    }
    else
    {
        cell.accessoryType = UITableViewCellAccessoryType.None
    }
    return cell
}      

Now change didSelectRowAtIndexPath like this

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{   
     tableView.deselectRowAtIndexPath(indexPath, animated: true)
     if (self.result.count != limit) {   
         if (self.result.contains(genreList[indexPath.row])) {
             let index = self.result.indexOf(genreList[indexPath.row])
             self.result.removeAtIndex(index)
         }
         else {
             self.result.append(genreList[indexPath.row])
         }
     }
     else {
         if (self.result.contains(genreList[indexPath.row])) {
             let index = self.result.indexOf(genreList[indexPath.row])
             self.result.removeAtIndex(index)   
         }
         else {
             let alertController = UIAlertController(title: "Oops", message:
            "You are limited to \(limit) selections", preferredStyle: .Alert)
             alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: {action in
         }))
             self.presentViewController(alertController, animated: true, completion: nil)
         }
     }
     stringRepresentation = result.joinWithSeparator("|")
     self.tableView.reloadData()
}

Note: Remove willSelectRowAtIndexPath method from ViewController now there is no need of that method.