1

In my cell i have a button. I added index row and action for this button with following code.

func showAllAction(sender:AnyObject) {
        self.performSegueWithIdentifier("showProduct", sender: sender)
    }

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("CartCell", forIndexPath:
        indexPath) as! CartTableViewCell

        cell.showAllButton.tag = indexPath.row
        cell.showAllButton.addTarget(self, action: "showAllAction:", forControlEvents: .TouchUpInside)

}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if segue.identifier == "showProduct" {
            let destinationController = segue.destinationViewController as! ProductController
            destinationController.shopItem = self.Items[sender.tag]
        }
    }

And when user click on button he would go to another page. But when i add new cells to table my indexes are wrong. How recalculate row path each time when i add delete etc..?

Now i delegate this process with NSFetchedResultsControllerDelegate

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {

        switch type {
            case .Insert:
                if let _newIndexPath = newIndexPath {
                    tableView.insertRowsAtIndexPaths([_newIndexPath], withRowAnimation: .Fade)
                }
            case .Delete:
                if let _indexPath = indexPath {
                    tableView.deleteRowsAtIndexPaths([_indexPath], withRowAnimation: .Fade)
                }
            case .Update:
                if let _indexPath = indexPath {
                    tableView.reloadRowsAtIndexPaths([_indexPath], withRowAnimation: .Fade)
                }
            default:
                    self.tableView.reloadData()
        }

        self.items = controller.fetchedObjects as! [Item]
    }
Arti
  • 7,356
  • 12
  • 57
  • 122

1 Answers1

1

The indexPaths should be correct unless you or the user edit the table (adding/removing/reordering cells.) It sounds like you are doing that, which means your approach won't work.

It would be messy and error-prone to go back and edit the tags on your cell's buttons when you insert/remove/reorder cells.

Better to ditch the approach of saving the item's row into the button tag. Instead get the origin of the button, convert it to the table view's coordinate space (Using convertPoint:toView: or convertPoint:fromView:) and ask the table view for the index path of that point using the UITableView method indexPathForRowAtPoint.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • can you provide please example? I use this answer: http://stackoverflow.com/questions/27429652/detecting-uibutton-pressed-in-tableview-swift-best-practices ```func showAllButtonPushed(sender:UIButton) { let buttonPosition = sender.convertPoint(CGPointZero, toView: self.tableView) if let indexPath = self.tableView.indexPathForRowAtPoint(buttonPosition) { sender.tag = indexPath.row self.performSegueWithIdentifier("showTable", sender: sender) } }``` but it doesn't work :( – Arti Nov 27 '15 at 08:13
  • Don't be so quick to ask for code. I told you what you needed to do, including the calls you needed to use. At least try to work it out for yourself without somebody else's code. You'll learn more if you figure it out for yourself, not copy/pasting. – Duncan C Nov 27 '15 at 14:48