tableView:dequeueReusableCellWithIdentifier问题与“全局”常量
请保存我的头发,或指出我的(明显的)错误。 我想在UITableViewCellStyleSubtitle
的子类中使用UITableViewCellStyleSubtitle的UITableViewStyle。
我在实现中定义了一个静态常量:
static NSString * const kAHCellIdentifier;
在viewDidLoad
我注册一个tableView类:
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kAHCellIdentifier];
然后在tableView:cellForRowAtIndexPath
我初始化单元格如下:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kAHCellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kAHCellIdentifier]; }
当运行应用程序(设备或模拟)单元格加载,但detailTextLabel不显示,但是,如果我像这样初始化,它可以正常工作*
我的猜测是,这个常量实际上并不是静态的,或者是有一个bug(8.0.2),或者是因为缺乏睡眠或者其他原因而完全缺失了某些东西。
还可以注意到,如果我不注册类,那么即使单元格标识符不同,也会出现编译器错误(预期),但不会出现错误(我猜测这是因为我可以为不同的单元格样式注册不同的类。
我错过了什么?
编辑
使用[tableView dequeueReusableCellWithIdentifier:kAHCellIdentifier forIndexPath:indexPath];
也没有效果。
较短的问题
为什么dequeueReusableCellWithIdentifier
返回nil,因此如果我在cellForRowAtIndexPath
方法调用中使用静态NSString,而不是如果我使用上面定义的类级全局常量,则使用单元格中的UITableViewCellStyle启动单元cell == nil
块。
额外
一些更多的testing产生了一些不同的结果。 如果你注册一个cell重用标识符的类,然后在cellForRowAtIndexPath
为cell指定一个不同的标识符,那么它就起作用了。 如果你给它与注册类相同的名称,那么它不会按预期工作。
回答
经过一些testing,@ MANIAK_dobrii的回答,一些清晰。
如果您想使用更新的单元出队方法dequeueReusableCellWithIdentifier:forIndexPath
并且需要使用非默认的UITableViewCellStyle
,则需要dequeueReusableCellWithIdentifier:forIndexPath
UITableViewCell
并重写initWithStyle
方法调用中的tableview样式。
如果你很乐意使用旧的方法,那么确保你没有注册一个类的重用标识符,否则将无法正常工作。
这很有趣,因为我刚刚在dequeueReusableCellWithIdentifier:
的文档中find了一个新的段落dequeueReusableCellWithIdentifier:
我没有看到上次我在那里看到:
如果您为指定的标识符注册了一个类,并且必须创build一个新的单元格,则此方法通过调用其initWithStyle:reuseIdentifier:方法来初始化该单元格。 对于基于笔尖的单元格,此方法从提供的nib文件加载单元格对象。 如果现有的单元可用于重用,则此方法将调用单元的prepareForReuse方法。
这是否意味着,如果你注册一个类,甚至dequeueReusableCellWithIdentifier:
将尝试创build单元格,如果它不是在重用队列中可用,并始终返回一个有效的单元格? 由于-dequeueReusableCellWithIdentifier:forIndexPath:
可用,我只使用它。 所以,我的猜测是你的
if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; }
永远不会被调用,并最终通过创build单元格
[[registred_class alloc] initWithStyle:STANDARD_STYLE reuseIdentifier:registred_reuse_identifier];
同时,你已经说过,如果你没有注册类,会得到编译时错误,这很奇怪,你不应该得到任何错误。
所以,我的解决scheme将是或:
1.不要通过-registerClass:forCellReuseIdentifier:
注册单元类-registerClass:forCellReuseIdentifier:
并使用-dequeueReusableCellWithIdentifier:
获取重用单元格或创build它们,就像现在这样做。 再次,使用oldschool的方法,你不注册任何东西,只是出现,如果有,创build,如果没有。
// I've put it here just for a clarification that that's doesn't matter for the case static NSString *const cellID = @"CellID"; // Just this, do not register anything, cell should get the same id as you ask // ie you should init cell with the same id you then try to dequeue - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if(!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; } cell.textLabel.text = @"Title"; cell.detailTextLabel.text = @"subtitle"; return cell; }
要么:
2.创buildnib,把一个UITableViewCell放在那里,使它的风格是UITableViewCellStyleSubtitle
并且注册该nib作为重用标识符,而不是registerNib:forCellReuseIdentifier:
的类registerNib:forCellReuseIdentifier:
另外,确保所有的标题/颜色/透明胶片都是正确的,这样您就不会将空string或零设置为单元格上的标签。