8

我无法理解这是如何工作的。我已经阅读了很多关于它的主题——比如UITableView dequeueReusableCellWithIdentifier TheoryHow 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 - 我在上面期望的行为)。

但是,我注意到当我将代码更改为 use[tableView dequeueReusableCellWithIdentifier:]时,它​​会创建一个新单元格,其contentView.frame宽度为 320(全宽)。以前,当我这样做时,dequeue...forIndexPath它会给出 302 的宽度,或单元格的视觉/“真实”宽度。为什么是这样?

另外,有没有办法指定 UITableViewCells regstiered 的样式以供重用?


解决方案:所以我发现这个线程UITableView cell.contentView.bounds.size.width Changes With Cell Reuse,它说当你将 autoresizingmask 设置为 UIViewAutoresizingFlexibleLeftMargin 时,当你尝试进行相对定位时它是固定的(contentView 宽度最初是完全宽度,但是当你展示它时它会缩小,所以如果你正确地计算它仍然会正确显示)。

我将 UISwitch 放置在右侧 - 当我设置自动调整大小蒙版时,它在第一次显示时起作用,但在我切换它时又移动了约 20 个像素。我不知道是什么导致了这种额外的转变,但我最终通过简单地将 UISwitch 设置为单元格的附件视图来解决它。

(这部分偏离了原始问题的主题,但如果有人偶然发现这可能会很有用)。对于任何特别想知道原始问题的人,答案在第一次编辑下。

4

4 回答 4

9

当您调用时[tableView registerClass: forCellReuseIdentifier:],您正在教表视图在您以后使用指定的ReuseIdentifier. 因此,当您稍后调用[tableView dequeueReusableCellWithIdentifier:]它时,它会:

A. 获取一个之前创建但当前未使用的单元格

或者

B. 创建您指定的类的新单元格

所以,当你出队时,你总会得到一个实例。如果你想自己创建新的单元格实例,initWithStyle:reuseIdentifier:那么你不应该在表格视图中注册一个类。或者,保留注册并添加逻辑以指定需要配置的所有内容(并考虑使用多个不同的单元类并重用标识符)。

于 2013-06-18T19:21:10.743 回答
0

因为第一次单元格为零,这就是为什么调用它的原因:

if (!cell) {
NSLog(@"New cell");
cell = [[UITableViewCell alloc] initWithStyle:someStyle reuseIdentifier:someIdentifier];
}

但是如果单元格已经准备好重用并且基本上它不是 nil - 它返回单元格并且它没有命中上面的 if 语句

于 2013-06-18T19:15:47.710 回答
0

来自https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006943的苹果文档

当被要求为表格视图提供新单元格时,从您的数据源对象调用此方法。如果一个可用的单元格可用,则此方法使现有单元格出列,或者使用您之前注册的类或 nib 文件创建一个新单元格。如果没有单元格可重用并且您没有注册类或 nib 文件,则此方法返回 nil。

dequeue 方法将

  1. 如果可用,则返回回收的电池

  2. 如果您注册了一个新单元格,请创建一个新单元格(您提到您这样做了)

  3. 如果这些都不为真,则返回 nil

我猜如果您删除注册(可能隐藏在 xib 中),那么您将得到 nil 结果。

于 2013-06-18T19:31:52.847 回答
-1

如果你看到 UITableView.h

从 iOS 6 开始,客户端可以为每个单元注册一个 nib 或类。

如果所有重用标识符都已注册,请使用较新的 - 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);
于 2015-01-27T08:19:21.383 回答