Since starting to compile my app with iOS 6 (and since also iOS 7) I\'ve started seeing this message. I know that the way that UITableViews go about managing cells is diffe
This is obviously an old question, but hopefully this can help anyone who still gets this issue in iOS8+ because this is still the top question that comes up for this particular error message.
I was using PINRemoteImage to async download an image to a UIImageView that was inside a custom UITableViewCell.
In order to resize the row properly (dynamic height cells using auto-layout) once the image had loaded, I called:
self.tableView beginUpdates;
self.tableView endUpdates;
I was then getting the "no index path for table cell being reused" message and the app was crashing. I had thought the PINRemoteImageManagerResult block was on the main thread, however it turns out that it wasn't - therefore ensuring that the begin/end updates was called on the main thread fixed the issue.
dispatch_async(dispatch_get_main_queue(), ^(void){
[self.tableView beginUpdates];
[self.tableView endUpdates];
});
As an addition to my previous post (in which I mentioned that this was apparently a bug with UIKit), I was able to find a workaround for my particular case (in which the message was related to some strange visualisation glitches on the table).
Apparently my custom cell's overridden -(void)setEditing:animated:
was taking too long to return.
My previous code was:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[self someAdditionalCode];
}
I was able to fix it by changing it to:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
// DRM: we want to perform the actions from this block in the main thread, but
// asynchronously to avoid excessive delays which were causing issues.
//
dispatch_async(dispatch_get_main_queue(), ^void()
{
[self someAdditionalCode];
});
}
Maybe this helps someone: i once had this error while refreshing a single table view cell. I meant to do something like
NSIndexPath *reloadRow = [NSIndexPath indexPathForRow:1 inSection:2];
[self._mainTableView reloadRowsAtIndexPaths:@[reloadWebViewRow]
withRowAnimation:UITableViewRowAnimationFade];
But accidentally, i typed
NSIndexPath *reloadRow = [NSIndexPath indexPathForItem:1 inSection:2];
Notice the difference of the two indexpaths: one is created with indexPathForItem
(wrong), the other with indexPathForRow
(correct).
This all resulted in very strange behaviour of the tableView and the error message in the headline.
Doing my endupdates after resignfirstresponder solved my problem (Have a UITextFIeld in my custom cell)
-(void)textfieldEditDone
{
....
[textField resignFirstResponder];
[self.tableView endUpdates];
I'd return the contentView of the UITableViewCell instead of creating a wrapper.. having constraint-jabble fixed in storybord in mind
return cell.contentView;
It seems like my issue was triggered when I was trying to update the UI within a portion of the code that was a callback from a web call. I resolved by forcing UI updates to happen on the main thread. I used code like this.
void runOnMainQueueWithoutDeadlocking(void (^block)(void)){
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
}
I call it as follows inside of the success block of my background web call.
runOnMainQueueWithoutDeadlocking(^{
[self.tableView beginUpdates];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
});