iosswiftuitableviewaccessoryview

Tap on Cell Accessory


I have a UITableView with custom cells. Usually when the user taps the cell, it triggers this function:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     //Segue to another view
}

If in that view they mark the cell as finished, when they return the code will add the standard check accessory.

When the cell isn't finished, I'd like an empty check that can be tapped (I know I can add a custom image accessory), with the tap allowing the user to skip the segue and quickly mark the cell as finished. But I can't seem to make both work:

  1. Tapping on the main body of the cell should call didSelectRowAtIndexPath
  2. Tapping on the accessory view (empty check mark) should call a different set of code.

I've tried accessoryButtonTappedForRowWithIndexPath but it doesn't seem to even get called.

func tableView(tableView: UITableView, accessoryButtonTappedForRowWithIndexPath indexPath: NSIndexPath) { 
     //Shortcut code to change the cell to "finished"
}

Is it possible to have clicking on the main body trigger one set of code and clicking on the accessory view trigger another? If so, how?


Solution

  • You should add a UIButton to your custom UITableViewCell. You can then add a target for that button called pressedFinished, by saying something like cell.button.addTarget(self, action: "finishedPress:", forControlEvents: .TouchUpInside) or something then in pressedFinished you can say something like:

    func pressedFinished(sender:UIButton)
    {
       let location = self.tableView.convertPoint(sender.bounds.origin, fromView: sender)
       let indexPath = self.tableView.indexPathForRowAtPoint(location)
       //update your model to reflect task at indexPath is finished and reloadData
    }
    

    It's generally not a great practice to use tags as they have no inherent meaning. Also tags mapped to indexPath.row will only work if the table has one section.

    Another option might be using UITableViewRowAction:

    override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath:      NSIndexPath) -> [AnyObject]? {
      let rowAction : UITableViewRowAction
      if model[indexPath].finished
      {
          rowAction = UITableViewRowAction(style: .Normal, title: "Mark as Unfinished", handler: {(rowAction:UITableViewRowAction,indexPath:NSIndexPath)->() in
          //mark as unfinished in model and reload cell
          })
     }else{
          rowAction = UITableViewRowAction(style: .Normal, title: "Mark as Finished", handler: {(rowAction:UITableViewRowAction,indexPath:NSIndexPath)->() in
          //mark as finished in model and reload cell
          })
      }
      return [rowAction]
    }