我无法理解其工作原理。我已经阅读了很多有关它的帖子 - 例如UITableView dequeueReusableCellWithIdentifier Theory和How does dequeueReusableCellWithIdentifier: work?。
但是,我的UITableView每次都会成功地将一个单元格出列(它永远不会为零),即使它首次加载也是如此。我的印象是类似的单元格应该使用相同的标识符,因此您只需要更改必要的内容。
由于
if (!cell) {
NSLog(@"New cell");
cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier];
}
永远不会被调用,我不确定我应该如何处理具有不同样式的同一个表中的单元格,因为该样式只能在初始化程序中设置。
我还尝试使用不同的单元格标识符,以确保它不会重用来自不同表格或其他内容的单元格。我正在使用[tableView registerClass: forCellReuseIdentifier:]
如果我理解,这种方法应该只返回已经移出屏幕的先前创建的单元格(隐藏,即可以重复使用)。那么为什么它第一次被调用时会返回一个单元格呢?
编辑:所以混淆是使用[tableView dequeueReusableCellWithIdentifier: forIndexPath:]
而不是[tableView dequeueReusableCellWithIdentifier:]
(第一个需要注册标识符,第二个将返回nil,如果没有可用的话 - 行为我期待以上)。
但是,我注意到当我将代码更改为使用[tableView dequeueReusableCellWithIdentifier:]
时,它会创建一个新单元格,其contentView.frame
的宽度为320(全宽)。之前,当我做dequeue...forIndexPath
时,它会给出302的宽度,或者单元格的视觉/“实际”宽度。这是为什么?
另外,有没有办法指定重新注册的UITableViewCells的样式?
解决方案:所以我找到了这个帖子UITableView cell.contentView.bounds.size.width Changes With Cell Reuse,它说当你将自动调整掩码设置为UIViewAutoresizingFlexibleLeftMargin时,它会在你尝试进行相对定位时修复(contentView宽度最初是完全的)宽度,但当你呈现它缩小时,所以如果你做正确的计算,它仍然会正确显示。
我正在将UISwitch定位在右侧 - 当我设置自动调整遮罩时,它在第一次显示时工作,但在我切换时移动了另外~20个像素。我不知道是什么造成了这个额外的转变,但我最后通过简单地将UISwitch设置为单元的附件视图来解决它。
(这是原始问题的部分偏离主题,但如果有人偶然发现它可能会有用)。对于任何想知道原始问题的人来说,答案都在第一次编辑之下。
答案 0 :(得分:9)
当您致电[tableView registerClass: forCellReuseIdentifier:]
时,您正在教授表格视图,以便您稍后使用指定的ReuseIdentifier
时该怎么做。因此,当您稍后致电[tableView dequeueReusableCellWithIdentifier:]
时,它将会:
一个。获取之前已创建且当前未使用的单元格
OR
B中。创建您指定的类的新单元格
所以,当你出队时,你总会得到一个实例。如果要使用initWithStyle:reuseIdentifier:
自己创建新的单元格实例,则不应使用表格视图注册类。或者,保留注册并添加逻辑以指定需要配置的所有内容(并考虑使用多个不同的单元类并重用标识符)。
答案 1 :(得分:0)
因为第一次单元格为零,这就是调用它的原因:
if (!cell) {
NSLog(@"New cell");
cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier];
}
但是如果单元格已经准备好重用并且基本上它不是nil - 它返回单元格并且它不会触及上面的if语句
答案 2 :(得分:0)
当系统要求为表视图提供新单元格时,请从数据源对象中调用此方法。如果现有单元格可用,则此方法会使现有单元格出列,或者使用先前注册的类或nib文件创建新单元格。如果没有单元可供重用,并且您没有注册类或nib文件,则此方法返回nil。
出队方法
返回已回收的单元格(如果有的话)
如果您注册了一个,则创建一个新单元格(您提到过这样做了)
如果这些都不成立,则返回nil
我猜你是否删除了注册(可能隐藏在xib中),那么你将获得nil结果。
答案 3 :(得分:-1)
如果你看到UITableView.h
从iOS 6开始,客户可以为每个单元注册一个笔尖或类。
如果注册了所有重用标识符,请使用较新的 - dequeueReusableCellWithIdentifier:forIndexPath
:以保证返回单元格实例。
从新的dequeue方法返回的实例在返回时也会正确调整大小。
(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
(void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);