在 UICollectionViewCell 上设置 .reuseIdentifier

Posted

技术标签:

【中文标题】在 UICollectionViewCell 上设置 .reuseIdentifier【英文标题】:Setting .reuseIdentifier on a UICollectionViewCell 【发布时间】:2012-11-08 02:40:44 【问题描述】:

我有一个特定的UICollectionViewCell 我想实例化自己,并添加到UICollectionView。为了使其工作,UICollectionViewCell 实例需要设置其.reuseIdentifier 属性。

通常,描述单元格的类或 Nib 会在集合视图中注册,并且集合视图会使用已设置的 .reuseIdentifier 实例化单元格,使用以下方法:

- registerClass:forCellWithReuseIdentifier:
- registerNib:forCellWithReuseIdentifier:

但是,由于我是在集合视图之外构建此单元格,因此这些不适用。

当我自己创建单元格时,似乎无法设置其.reuseIdentifier(因为它是只读属性,并且没有初始化它的init... 方法)。

如果未设置.reuseIdentifier,则在添加单元格时UICollectionView 会引发异常。此行为与 UITableView 不同,在 UITableView 中,重用标识符是可选的。

设置集合视图单元格的重用标识符的简单解决方法是将其嵌入.xib 文件并使用Identifier 框,然后使用

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

然后我可以通过上面实例化的UICollectionViewCell,一切正常。

...但这似乎是一个非常愚蠢和任意的箍跳。有没有其他方法可以在没有.xib-wrapper 绕道的情况下在单元实例上设置此属性?


更新:Apple 的文档是这样说的:

为了简化代码的创建过程,集合视图要求您始终将视图出列,而不是在代码中显式创建它们。

...这实际上是不正确的,因为它不需要这个(即,只要设置了标识符以某种方式,外部实例化的单元格就可以正常工作,例如,如果从 @ 加载987654338@),并且在我的特定用例中它也没有“简化我的代码的创建过程”(而是需要一个额外的文件;此外,要求集合视图创建这几个复杂的一次性操作会很麻烦) .

但上述内容似乎暗示该问题的答案是否定的:故意“难以”创建可用单元格,除非让集合视图将其出列。

【问题讨论】:

也许这有帮助:***.com/questions/12729612/…。 (它适用于表格视图单元格,但我认为它也应该适用于集合视图单元格。) 谢谢,这是一个很好的尝试。我还想知道setValue:forKey 是否“围绕”readonly 位。 :) 【参考方案1】:

我很抱歉这么说,但我认为您将不得不接受这样一个事实,即 UICollectionView 是生产 UICollectionViewCells 的唯一 Apple 品牌工厂。因此,如果您有两个集合视图要在其中显示完全相同的 object,那么您就不走运了!

好消息是,如果您有两个集合视图,您希望在其中显示一个 看起来 与另一个完全相同的单元格,那么您可以完成任务。很简单:

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


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

同时,无论哪个类拥有 UICollectionView cv1 和 cv2

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

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

而且它们的数据源看起来是一样的

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

   MyCollectionViewCell *cell;

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

   [cell refreshCellWithObject:obj];

   return cell;

【讨论】:

“我认为你将不得不接受这样一个事实,即 UICollectionView 是生产 UICollectionViewCells 的唯一 Apple 品牌工厂。”但显然可以使用 xib 创建 UICollectionViewCells,而无需 UICollectionView。 您可能是对的,但今年早些时候,经过长时间的实验,我决定采用 Apple 推荐的做法。在***.com/q/15939234/1224741 上查看我的一些相关的问答。它有来自 Apple 工程师的一段与此相关的引言。 能否提供 refreshCellWithObject: 方法的实现?如何使用重用标识符刷新 Cell。 该方法是您根据给定对象实现填充所有单元格视图的方法。【参考方案2】:

使用这两种方法。

– registerNib:forCellWithReuseIdentifier:
– dequeueReusableCellWithReuseIdentifier:forIndexPath:

查看苹果的UICollectionView Class Reference

【讨论】:

上述方法如宣传的那样工作,但这并不能回答我的问题。我在这里所做的是将一些任意一次性单元格传递给正在其他地方构建的集合视图。另外,我要问的是如何避免使用.xib。 你要构造一个 UICollectionViewCell 使用代码,然后在其他地方使用? 正确,我想在 UICollectionViewCell 子类上调用某种 init 方法,然后在集合视图中显示该特定实例。 我已经搜索过了,我认为您只能从 .xib 文件中加载它。对此感到抱歉。 我认为可能有一些技巧可以用来直接设置属性;请参阅有关该问题的第一条评论。但是使用.xib 似乎是最安全的方式。

以上是关于在 UICollectionViewCell 上设置 .reuseIdentifier的主要内容,如果未能解决你的问题,请参考以下文章

在 UICollectionViewCell 上设置 .reuseIdentifier

在 UICollectionViewCell 中更新 UITableView

如何在 UICollectionViewCell 中添加 UICollectionView?

如何在 UICollectionViewCell 上设置 UILabel?

UICollectionViewCell 边框/阴影

如何在 iOS 7 中刷新 UICollectionViewCell?