dequeueReusableCellWithIdentifier not reusing cells
I have a UICollectionView
with a custom cell subclassing UICollectionViewCell
. And in the code I have done the following:
[self.collectionView_ registerClass:[AHPinterestCell class]
forCellWithReuseIdentifier:@"AHPinterestCell"];
this is what goes in my cellForItem
AHPinterestCell *cell =
(AHPinterestCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"AHPinterestCell"
forIndexPath:indexPath];
however, it seems that it's not reusing the cell. In my collection view per screen it is showing about 9-10 cells, however when I do infinite scroll and then I call insertItemsAtIndexPath
it calls the initWithFrame
method on my custom cell, while it should probably reuse the cells I already have. Why is this?
EDIT:
I am adding a sample demo project that illustrates the problem, the link to the xcode project can be found here. It's essentially doing an infinite scroll when you reach to the bottom, it just appends more stuff into it. But when you do so it's going to call the init method again.
In short, your code works fine. As expected, as cells scroll off the screen, they are eventually flagged as being available for reuse. And when you call dequeueReusableCellWithReuseIdentifier
, if there is a cell available for reuse, it will do so. If not, it creates one.
The time that you'll see a lot of cells being created is if you scroll fast or continually. But if you do short little scrolls, let go, pause, let the UI catch up and repeat, then you'll see very few cells being created.
I interpret this as meaning that iOS prioritizes the UI and the creation of new cells over the dequeuing of old cells, allowing their reuse. So if you flip quickly, it has trouble catching up and flagging old cells as available for reuse. This is probably not altogether bad, as this is probably what gives collection views such smooth flow. Flagging old cells for reuse is one of the less important things for iOS to do here. But clearly if memory is tight, this might be a problem.
By the way, if you put a NSLog
in dealloc
, too, you'll notice that when the UI finally catches up after doing a really fast scroll through the collection view, it clearly has some logic that says "gee, I've got more spare cells than I really need, I'm going to get rid of some of these." It's a pretty clever implementation, actually. A focus on speed, but with some memory optimizations that take place once the UI quiets down.
Agreed, I have the same problem, but I thought of creating a category to give me the visible cell, if available.
// Header file UITableView+VisibleCell.h"
@interface UITableView (VisibleCell)
- (UITableViewCell*) visibleCellForRowAtIndexPath:(NSIndexPath *)indexPath;
@end
// Implementation file UITableView+VisibleCell.m
#import "UITableView+VisibleCell.h"
@implementation UITableView (VisibleCell)
- (UITableViewCell*) visibleCellForRowAtIndexPath:(NSIndexPath *)indexPath
{
for( UITableViewCell* currentVisibleCell in self.visibleCells )
{
NSIndexPath* currentPath = [self indexPathForCell: currentVisibleCell ];
if( [currentPath isEqual:(id) indexPath] )
{
return currentVisibleCell;
}
}
return nil;
}
@end
You can also start by getting the visible cell then return cellForRowAtIndexPath instead of nil, its a question of style. (I needed this to retrieve a UITextField with a given tag in a given cell to make it becomeFIrstResponder, but cellForRowAtIndexPath kept re-allocating my cell, very frustrating.
Turn off accessibility from your device settings. Its a bug . I have got the same issue on my iPad mini.
链接地址: http://www.djcxy.com/p/68650.html