Souljacker
Souljacker

Reputation: 774

Delete UITableViewCell using custom UIButton

I have encountered this error when trying to delete a cell, using a custom button.

* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM removeObjectAtIndex:]: index 1 beyond bounds [0 .. 0]'

Heres how my code is structured. I have a custom UITableViewCell that contains a UIButton which has an action that deletes the cell. The action for deleting the cell is in my main View controller, that contains the actual indexPath for the cells. This structure works fine.

Heres the action to delete the cell.

NSIndexPath *indexPath = [self globalIndexPath];

[self.array removeObjectAtIndex:[indexPath row]];
[db deleteTaskAtIndex:[indexPath row]];

[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationFade];

When I declare the indexPath above, the globalIndexPath property is set in my cellForRowAtIndexPath, giving it the value of the original indexPath. This is how I declared it.

[self setGlobalIndexPath:indexPath];

Now I have laid some NSLogs here an there to log the indexPath. For example in the viewWillAppear method and the viewDidLoad method, and both give me the accurate indexPath, and I even checked the array outputs and all of them return accurate results, so I really don't know why it's giving me the error.

Here is the code in my custom cell, to detect when the button is tapped.

NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
if (!notificationArray || !notificationArray.count)
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"DeleteSignal" object:nil];
}
else
{
    UILocalNotification *notif = [notificationArray objectAtIndex:[checkbox tag]];
    [[UIApplication sharedApplication] cancelLocalNotification:notif];
}

And then I delete the the cell using the NSNotificationCenter with the key DeleteSignal.

Upvotes: 1

Views: 302

Answers (1)

Andy Friese
Andy Friese

Reputation: 6469

If you are setting the globalIndexPath in cellForRowAtIndexPath (and nowhere else), globalIndexpath will always know the indexPath for the last cell, which got created or dequeued, not the one where the user might actually use the button. Seems already broken by design. Or are your cells that large that only one is visible?

At first I would try setting the tag of your UIButton of your cell in cellForRowAtIndexPath

myButton.tag = indexPath.row + SOMEOFFSETTOASSUREYOURTAGDOESNTGET0;

and then get the indexPath in your action via this tag:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(UIButton*)sender.tag - OFFSET inSection:0];

Of course that only works if you have just one section. If you need to handle multiple sections you could use an array which contains all your indexPaths and set the tag of your UIButton to the index of that indexPath in your array.

UPDATE

While it's technically possible to (mis)use NSNotificationCenter for what you are doing, I would really advise you to walk through this tutorial.

Upvotes: 1

Related Questions