Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
675 views
in Technique[技术] by (71.8m points)

objective c - Setting .reuseIdentifier on a UICollectionViewCell

I have a particular UICollectionViewCell that I want to instantiate myself, and add to a UICollectionView. In order for this to work, the UICollectionViewCell instance needs its .reuseIdentifier property to be set.

Normally, the class or Nib that describes the cell is registered with the collection view, and the collection view instantiates the cell with its .reuseIdentifier already set, with these methods:

- registerClass:forCellWithReuseIdentifier:
- registerNib:forCellWithReuseIdentifier:

However, since I am constructing this cell outside of the collection view, these do not apply.

When I create the cell myself, there appears to be no way to set its .reuseIdentifier (because it is a readonly property, and there are no init... methods that initialize it).

When .reuseIdentifier is not set, the UICollectionView throws an exception when the cell is added. This behavior is different from UITableView, where reuse identifiers were optional.

An easy workaround to set the collection view cell's reuse identifier is to embed it in a .xib file and use the Identifier box, then create an instance of the cell with

[NSBundle.mainBundle loadNibNamed:@"MyCellName" owner:self options:nil][0];

I can then pass the above-instantiated UICollectionViewCell and everything works fine.

...but that seems like a pretty silly and arbitrary hoop to jump through. Is there some other way to get this property set on the cell instance without the .xib-wrapper detour?


Update: Apple's documentation says this:

To simplify the creation process for your code, the collection view requires that you always dequeue views, rather than create them explicitly in your code.

...which is actually not true, because it doesn't require this (i.e., externally-instanced cells work fine as long as their identifier is set somehow, e.g. if loaded from a .xib), and it also doesn't "simplify the creation process for my code" in my particular use case (rather requires an extra file; further it would be messy to require that the collection view create these few complex one-offs).

But the above does seem to imply that the answer to the question is no: it's intentionally "difficult" to create a usable cell except by having the collection view dequeue it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm sorry to say it, but I think you're going to have to accept the fact that UICollectionView is the sole Apple-branded factory for producing UICollectionViewCells. So if you have two collection views in which you want to display the exact same object, you're out of luck!

The good news is that if you have two collection view in which you want to display a cell that looks exactly the same as in the other, then you can accomplish your task. It's easy:

@interface MyModelClass : NSObject
  // a bunch of data
@end


@interface MyCollectionViewCell : UICollectionViewCell
-(void)refreshCellWithObject:(MyModelClass *)object;
@end

Meanwhile, in whichever classes own the UICollectionView cv1 and cv2

[[self cv1] registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"MyCollectionViewCell"];

and

[[self cv2] registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"MyCollectionViewCell"];

And their data sources can look the same

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
   MyModelObject *obj = [self theObjectIWant];

   MyCollectionViewCell *cell;

   cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCollectionViewCell" forIndexPath:indexPath];

   [cell refreshCellWithObject:obj];

   return cell;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...