Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I required to call UICollectionView's dequeueCell: from within the data source's cellForPath:?

I really, really want to provide 'static' cells to my UICollectionView, ala the old days with UITableView. But I know that we good boys and girls must use dequeueReusableCellWithReuseIdentifier:forIndexPath: as a factory for our cells. So I propose the following scheme, and request feedback on its potential. So far, it is working for me, but I dread an unknown gotcha.

#import "MyCellClass.h"

@implementation MyViewController {
   MyCellClass *_cell0; // etc - many are possible. could store in array
}

-(void)viewDidLoad {
   // assume MyCellClass has a +nib and +reuseId. The reader understands.
   [_collectionView registerNib:[MyCellClass nib] forCellWithReuseIdentifier:[MyCellClass reuseId]];
}

-(void)viewDidAppear:animated {
   // this is where the fun begins. assume proper counts coming from the datasource
   NSIndexPath *indexPath = [NSIndexPath indexPathWithRow:0 inSection:0];
   _cell0 = [[self collectionView] dequeueReusableCellWithReuseIdentifier:[MyCellClass reuseId] forIndexPath:indexPath];
   // etc
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
   if ([indexPath row] == 0) return _cell0;
   // etc
}

I deliberately gloss over details such as configuring the cell. Madness? Genius? Just status quo? It seems to be working so far, but I fear that, somehow, Apple expects dequeue to be called from within cellForPath. Any thoughts?

like image 361
QED Avatar asked Apr 11 '13 01:04

QED


2 Answers

Response from the Apple TSI Guy:

Although you said your app works, you really should use "dequeueReusableCellWithReuseIdentifier" from within the data source method "cellForItemAtIndexPath". That is the supported use pattern. Don't try to hold on you MyCellClass, let the collection view manage that and it will ask you to dequeue it if necessary.

I'm going to pout a little, change my code, and then issue an enhancement request. But I tell you it worked just fine!

like image 200
QED Avatar answered Nov 14 '22 22:11

QED


The only reason for calling dequeueReusableCellWithReuseIdentifier:forIndexPath: is to reuse cells. But a "static" collection view? How many cells are we talking about? If I had a collection view small enough that it never scrolled, I would consider not bothering to reuse cells at all. That would certainly solve the problem neatly. After all, a static table from the storyboard isn't reusing cells; that is what makes it static. So I would say, drop the stuff about dequeueReusableCellWithReuseIdentifier:forIndexPath altogether and just supply cells when asked.

There is nothing magical about dequeue; it's just a way of finding out whether there are any cells in the reuse pile, and getting one if so. After all, consider how table views worked in, say, iOS 4. You said dequeue, but if there were no reusable cells to give back, the table returned nil and you had to alloc-init your own cell or pull it out of a nib, yourself. Well, you are proposing to do that for all items in the collection view. Go right ahead.

like image 34
matt Avatar answered Nov 14 '22 22:11

matt