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 different in iOS 6 but I haven't needed to modify my code for it to keep working. But I'm concerned this message may point to some potential issue that I'm not yet seeing. Can anyone shed any light?
14 Answers
I started to get this error showing up in the log from iOS 7 beta 5 onwards, including in the iOS 7 GM/Release build, whilst never having had it happen in my app in iOS 6 or the earlier iOS 7 betas. After a lot of experimenting I found the cause:
I was using UITableViewCell
objects for my section header views and returning them in tableView:viewForHeaderInSection:
. This appears to be common practice, especially since iOS 5 when it became easy to design a section header view as a prototype table view cell in a StoryBoard with Interface Builder.
When I changed my app to use just regular UIView
subclasses for my section header views, the errors went away and, more importantly, my table view stopped randomly deleting section headers!
It would appear that (since iOS 7 beta 5) UITableView
is internally maintaining a mapping of all the UITableViewCell
objects in its view hierarchy and their respective index paths. Since a section header (or a table view header of footer) doesn't have an index path, if you use a UITableViewCell
object for these views, the table view will get confused when it finds a UITableViewCell
for which it doesn't have an index path, resulting in the "no index path for table cell being reused" error and, if you're unlucky, display glitches in your table view:
UPDATE: if you have access to the Apple Dev Forums, here's the thread about it (which I started): https://devforums.apple.com/message/882042#882042
As suggested in that thread, if you don't want to re-factor much, you can create a UIView
wrapper around your UITableViewCell
and return that as the section header view.
UIView *view = [[UIView alloc] initWithFrame:[cell frame]];
[view addSubview:cell];
return view;
Note however that this "wrapper" UIView
approach will not play well with AutoLayout and device rotation, so I suggest that you use a UIView
subclass for header and footer cells, not a UITableViewCell
subclass as explained in the main part of the answer.

- 14,448
- 7
- 58
- 86
-
3Awesome! I was experiencing the header disappearing as well. This is going to save me a lot of time over the next few days. Thank you! So were you able to design your headers in the Storyboard still? Do you just change the class to a UIView within the Storyboard settings?? – Chris Wagner Sep 12 '13 at 16:46
-
2@ChrisWagner no, I just created a separate standalone XIB file for the header cell and then load it like this: `NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"SectionHeader" owner:self options:nil]; SectionHeaderView *sectionHeaderView = nib[0];` You can't create a standalone view in a StoryBoard which isn't a view controller as far as I know. – mluisbrown Sep 12 '13 at 17:34
-
2@ChrisWagner an alternative which also seems to work is to just create a `UIView` with the same frame and then add your `UITableViewCell` object as a subview, so creating a `UIView` wrapper for the section header cell. – mluisbrown Sep 12 '13 at 17:45
-
There's another good idea, I'll try that for simplicity sake. I'd rather the design be in the storyboard with everything else. – Chris Wagner Sep 12 '13 at 17:51
-
1This is amazing. I was having this problem and thought it was because my hacky animations. It solved most of my problems (even with weird black background appearance behind the headers) with table views. Thank you very much. – czechboy Sep 20 '13 at 10:14
-
Wrapping the UITableViewCell inside UIView (and still using the Storyboard prototype from [tableView dequeueReusableCellWithIdentifier:...] solved the issue with disappearing header view in iOS 7. – Markus Rautopuro Mar 22 '14 at 06:59
-
Excellent! Works like a charm. Initially I was returning the contentView or the tableviewcell iteself, but it doesn't work well. – Dmitri Pavlutin Nov 03 '14 at 07:56
-
1This didn't automatically work for me in both landscape and portrait when the view controller uses AutoLayout and the tableview is defined in Interface Builder. – Bart van Kuik Feb 09 '15 at 13:58
-
7As an alternative to @mluisbrown suggestion, this worked for me: return cell.contentView; – Andrew Duncan Feb 10 '15 at 00:55
-
@AndrewDuncan The problem with simply returning the `contentView` is that all the targets/delegates on the cell will stop working. So only do this if you have static content – pixelfreak Oct 21 '15 at 20:05
-
I was also doing same, i.e returning UITableViewCell (nib) object from, viewForHeaderInSection, and getting this message logged 'no index path for table cell being reused header'. Also i was adding and removing cell dynamically inside section on tap of headerView, that was also not working smoothly. After returning view object it start working very flawlessly. Thanks! – Bharat Modi Feb 08 '16 at 09:54
-
@mluisbrown is this answer still relevant in iOS 10, XCode 8.3?..I'm having a similar issue and wanted to ask if you can take a look at it? http://stackoverflow.com/questions/43061719/dynamic-cell-re-sizing-with-uitextview-within-uitableviewcell-causes-warning – Pangu Mar 28 '17 at 17:19
-
@Pangu haven't tried this recently, but if you're using a `UITableViewCell` for a header or footer view then that's your problem. Try using just a regular `UIView` subclass. – mluisbrown Mar 29 '17 at 12:37
I'd return the contentView of the UITableViewCell instead of creating a wrapper.. having constraint-jabble fixed in storybord in mind
return cell.contentView;

- 394
- 4
- 11
-
1This is a better answer than the one that's accepted, because it automatically works in both landscape and portrait when the view controller uses AutoLayout. – Bart van Kuik Feb 09 '15 at 13:57
-
Thank you. The accepted answer fails to work in iOS 8 on occasions but this one still works! – Eric Chen Apr 04 '15 at 09:56
-
2Background color is lost on Xcode 7.0.1 / iOS 8/9 (used to work for Xcode 6), so I have to go back to the accepted answer. – Eric Chen Oct 10 '15 at 11:13
-
The accepted answer suggests using a `UIView` subclass as a header / footer cell not a `UITableViewCell` subclass. This will always work, even with AutoLayout (@BartvanKuik). The `UIView` wrapper solution is a quick fix alternative. – mluisbrown Feb 08 '16 at 10:03
-
Background color is only lost because you probably applied it to the `UITableViewCell` `view`, apply it to the `contentView` and it should appear correctly, at least that was the easy fix for me. This answer is a much easier fix if you've already wired your section headers up as cells in a storyboard. – RyJ Aug 19 '16 at 14:48
I had the same problem and it took me few hours to hunt down the issue. Turns out I was calling [textField becomeFirstResponder]
while setting up cells (here the textField was part of a custom tableviewcell); [textField becomeFirstResponder]
in turns posts keyboardWillShow notification which in turn caused the tableview to prematurely load itself thus causing the infamous "no index path for table cell being reused” message. Once I removed that call, problem disappeared.

- 1,273
- 1
- 15
- 26
-
OMG!!! I spent two days trying to figure out what's going on. Who would have thought it is setting first responder! – user1366265 Nov 20 '15 at 14:35
-
1I had this problem too, I did wrap the call like this: `dispatch_async(dispatch_get_main_queue(), { self.textField.becomeFirstResponder() })` and the problem disappeared – juanjo Nov 29 '15 at 20:39
-
This helped lead me to the source of my problem. I was actually able to becomeFirstResponder while setting up the cell, however, I had to also make sure it was explicitly resigned later in the workflow. That and ensuring that my reloadRowsAtIndexPaths methods were all running on the main thread resolve my issues. – Scott D Sep 07 '16 at 15:34
Addition to the accepted answer (mluisbrown), I needed to add an autoresizingMask to the header cell, since mine contained a multi-line label, i.e.
UIView *view = [[UIView alloc] initWithFrame:[cell frame]];
cell.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[view addSubview:cell];
return view;

- 1,037
- 1
- 13
- 20
-
-
Rather than using a `UIView` wrapper, it would be better to make your header / footer cells `UIView` subclasses, not `UITableView` subclasses. That way you wouldn't have to add an autoresizing mask. – mluisbrown Feb 08 '16 at 10:18
This is an internal UIKit bug - as mentioned in Apple's own dev forums. It's supposedly fixed in newer versions of xcode, although I wasn't able to find info regarding which version fixes this.

- 1,997
- 18
- 20
-
Ah thanks. I did do a search for the exact phrase in Google but nothing came up. Perhaps it hasn't been indexed yet. Don't suppose you happen to have a direct link do you? – Nathan Brown Oct 07 '12 at 21:51
-
1You have to be registered as a developer in Apple's Dev portal to access the thread. First log in to [Apple's Dev Portal](http://developer.apple.com). Then go to "Member Center", and "Apple Developer Forums". In the search box look for "no index path for table cell being reused". You will find one thread with the explanation I posted above. Unfortunately not much more info is available, but they do recommend that you post a bug report. – diegoreymendez Oct 07 '12 at 21:59
-
Of course. It didn't occur to me that Google wouldn't have access to the forums. Thanks! – Nathan Brown Oct 10 '12 at 18:44
-
-
1@ChrisWagner, see my [answer](http://stackoverflow.com/a/18769328/368085) below for a possible solution for iOS 7. – mluisbrown Sep 12 '13 at 16:13
-
@CW0007007 maybe my [answer](http://stackoverflow.com/a/18769328/368085) below can help you. Apologies for the duplicate comment, but you can't @-reply to more than one person at a time. – mluisbrown Sep 12 '13 at 17:38
-
I had this problem because a textField subview of my custom tableview cell had the property clearOnInsertion set to TRUE. – CW0007007 Sep 17 '13 at 11:37
-
I think this is desired behaviour, the answer that has a workaround and works is below: http://stackoverflow.com/a/18769328/909246 – czechboy Sep 20 '13 at 10:16
-
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];
});
}

- 1,997
- 18
- 20
Doing my endupdates after resignfirstresponder solved my problem (Have a UITextFIeld in my custom cell)
-(void)textfieldEditDone
{
....
[textField resignFirstResponder];
[self.tableView endUpdates];

- 1,330
- 1
- 12
- 21
For the record, I encountered this message too when running under iOS 6. It appears that some code either inherited or imported had something like this:
(NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section {
NSInteger rows = 0;
if ([delegate respondsToSelector:@selector(numberOfItemsInSection:)]) {
rows = [delegate numberOfItemsInSection:section];
[tableView beginUpdates];
[tableView endUpdates];
}
}
When the beginUpdate: / endUpdate: sequence was removed, the problem magically disappeared.

- 3,327
- 6
- 30
- 47

- 21
- 2
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];
});

- 4,880
- 1
- 25
- 34
Well, I just used the better part of a day trying to figure this out, so hopefully this alternative explanation saves somebody else some time.
I had a tableview which was giving this message sometimes, when loading. It turned out to be caused by KVO notifications for Core Data objects firing while the view was loading. (On observing a change, my controller tried called reloadData on the tableview in question. Fixed by not observing the objects until the view had finished loading (previously I started observing the object once it was assigned via the accessor)
TLDR: Check to see if you might be trying to reload your data from something other than the main thread.

- 1,883
- 1
- 14
- 17
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.

- 1,220
- 17
- 35
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];
});

- 463
- 4
- 7
-
well after testing my code a bit more i see that the issue has came back. – Brackston Mayhall Jan 16 '15 at 06:05
Yet another condition...
This happened when, not wanting a header, I returned nil
.
Fix:
func tableView(tableView: UITableView,
titleForHeaderInSection section: Int) -> String? {
return ""
}

- 47,376
- 28
- 140
- 179