简体   繁体   中英

UITableView has randomly disappearing cells

I have a fairly simple UITableView which uses an NSArray of flight bookings, and displays one cell per booking. Recently customers have raised an issue (which I can only very occasionally reproduce) whereby some of the cells are completely hidden. The space for them is there, but there's just a gap where they should be.

The table has a header and footer so I can see the gaps (it's not just that there are less elements).

Example screenshot here: http://myflightsapp.com/images/missing-cells.png

It really is intermittent, because if I restart the app, the issue goes away.

I've tried replacing cellForRowAtIndexPath with a very simple 2 liner to just return a completely standard UITableViewCell with a text label, and it displays the same issue, so for me that rules out the Nib/Custom class being the issue.

The heightForRowAtIndexPath always returns a constant, so it's not showing a zero height row by mistake.

There's only ever 1 section to the table.

I've put debug in the numberOfSectionsInTableView method and it's always returning the correct number (2 in this example)

I've put debug in the cellForRowAtIndexPath, from which I've learnt: 1) If I drag the table view up high enough (so the cells disappear off the screen) and let go again, in circumstances when the issue is showing, it doesn't call cellForRowAtIndexPath again to try and redraw the cells when the table scrolls back into view, but when the issue is not there (ie the cells are all visible) it does call cellForRowAtIndexPath again for each cell.

2) At no point do any of the cells have the 'hidden' property true.

From adding debug elsewhere (eg a temporary button) I can manually invoke the cellForRowAtIndexPath method for a cell which is not displayed, and it returns what seems to be a valid cell.

So my question is, what can cause the issue I'm seeing? I'm running out of places to put debug to see where the issue may be.

Would massively appreciate any help - what am I missing?

What's probably causing the issue is that you don't have enough cells to reuse. Without seeing your code, I'm just speculating, but here's what can cause your issue:

Let's say your table is 100 points high and each cell is 10 points. Then your table, at any given time, has the 10 (or 11) cells that are currently in view in memory, as well as the 10 out of view above and 10 out of view below. So, the table has about 30 cells that it creates and then reuses over and over again.

It seems that there aren't enough cells being created to be reused in some situations.

Just a couple thoughts on how to "fix" the situation for you:

  1. Use [myTableView reloadData] when the table view contentOffset.y changes by more than table view frame.size.height . This will call the cells in view to be recreated. I do not recommend this method as it can be intense if there's a lot of data or a lot of cells that need to be recreated.
  2. Find how many cells are actually being created. You could add a tag to each cell and log each time a cell is brought into view. This might give you a better perspective on how cells are reused.
  3. Depending on the number of cells that you need, you could create each cell, load it into an array, and then return a unique cell for cellForRowAtIndexPath . Depending on the number of cells that you need, I think this might be the best option for you.

With help from Apple Dev Technical Support... I've resolved it. For the benefit of anyone else that comes across it, the reason was that I was accidentally calling the methods to reload the table from a secondary thread instead of on the main thread.

To resolve, I used the following

[self performSelectorOnMainThread:@selector(refreshMethod) withObject:nil waitUntilDone:YES];

And so far so good.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM