DequeueReusableCellWithIdentifier does not reuse cells

I have a UICollectionView with a custom subclass of UICollectionViewCell cells. And in the code, I did the following:

  [self.collectionView_ registerClass:[AHPinterestCell class] forCellWithReuseIdentifier:@"AHPinterestCell"]; 

this is what happens in my cellForItem

  AHPinterestCell *cell = (AHPinterestCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"AHPinterestCell" forIndexPath:indexPath]; 

however, it does not appear to be reusing the cell. In my collection view, about 9-10 cells are displayed on the screen, however when I do an infinite scroll and then I call insertItemsAtIndexPath , it calls the initWithFrame in my custom cell, while it should probably reuse the cells that have I already have, Why is it?

EDIT:

I am adding an example demo project that illustrates the problem, a link to the xcode project can be found here . In fact, making an endless scroll when you reach the bottom, it just adds more things to it. But when you do, it will call the init method again.

+7
source share
3 answers

In short, your code is working fine. As expected, when the cells scroll from the screen, they are ultimately marked as reusable. And when you call dequeueReusableCellWithReuseIdentifier , if there is a cell available for reuse, it will do it. If not, he creates one.

The time you see a lot of cells being created is scrolling quickly or continuously. But if you make short small scrolls, release, pause, let the user interface catch up and repeat, then you will see very few created cells.

I interpret this as meaning that iOS prioritizes the user interface and the creation of new cells to delete old cells, which allows them to be reused. Therefore, if you switch quickly, it has problems finding and placing old cells available for reuse. This is probably not entirely bad, as it is probably what gives the collection such a smooth flow. Marking old cells for reuse is one of the less important things for iOS. But it is clear that if the memory is dense, it can be a problem.

By the way, if you put NSLog in dealloc , you will also notice that when the user interface finally catches up after a very fast scrolling of the collection, it clearly has logic that says "Lord, I have more spare cells than I really need, I will get rid of from some of them. " This is actually a pretty smart implementation. Focus on speed, but with some memory optimizations that occur when the user interface closes.

+4
source

I agree, I have the same problem, but I thought about creating a category to give me a 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, and then return cellForRowAtIndexPath instead of nil, this is a style question. (I needed this to get a UITextField with a given tag in a given cell to make it beFIrstResponder, but cellForRowAtIndexPath continued to redistribute my cell, very frustrating.

0
source

Disable access to the settings of your device. This is mistake. I have the same problem on my iPad mini.

0
source

All Articles