Am I required to call UICollectionView's deque

2020-03-19 04:08发布

问题:

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?

回答1:

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!



回答2:

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.



回答3:

Check out my MBStaticCollectionView, it enables you to define static UICollectionView cells from the Interface Builder without the need to define a datasource.