Setting .reuseIdentifier on a UICollectionViewCell

孤街醉人 提交于 2019-12-18 06:14:44

问题


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.


回答1:


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;
}



回答2:


Use these two methods.

– registerNib:forCellWithReuseIdentifier:
– dequeueReusableCellWithReuseIdentifier:forIndexPath:

See apple's UICollectionView Class Reference



来源:https://stackoverflow.com/questions/13281631/setting-reuseidentifier-on-a-uicollectionviewcell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!