tableView:dequeueReusableCellWithIdentifier与“global”相关的问题不变 [英] tableView:dequeueReusableCellWithIdentifier issues with "global" constant

查看:77
本文介绍了tableView:dequeueReusableCellWithIdentifier与“global”相关的问题不变的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请保存我的头发或指出我的(明显的)错误。我试图在子类UITableViewController中使用 UITableViewCellStyleSubtitle 的UITableViewStyle。

Save my hair, please or point out my (obvious) error. I am trying to use a UITableViewStyle of UITableViewCellStyleSubtitle in a subclassed UITableViewController.

我在实现中定义了一个静态常量:

I define a static constant in the implementation:

static NSString * const kAHCellIdentifier;

viewDidLoad 我注册了一个tableView类:

In viewDidLoad I register a tableView class:

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kAHCellIdentifier];

然后在 tableView:cellForRowAtIndexPath 我初始化单元格如下:

Then in tableView:cellForRowAtIndexPath I initialise the the cell as follows:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kAHCellIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kAHCellIdentifier];
}

运行应用程序(设备或SIM卡)时,单元格会加载,但detailTextLabel不会但是,如果我像这样初始化,它可以正常工作*

When running the app (device or sim) the cells load but the detailTextLabel doesn't show, however if I initialise like this, it works correctly*

我的猜测是常量实际上不是静态的,或者存在错误(8.0。 2),或者由于睡眠不足或其他原因,我完全缺少某些东西。

My guess is that the constant is not actually static, or that there is a bug (8.0.2), or there is something that I am missing completely due to lack of sleep or whatever.

还可以注意到,如果我没有注册该类,则存在编译器错误(预期),但即使单元标识符不同(即我想是可以预期的,因为我可以为不同的单元格样式注册不同的类。

It can also be noted, that if I don't register the class there is a compiler error (expected) but no error even though the cell identifiers are different (which I guess is expected as I could register different classes for different cell styles.

我缺少什么?

修改

使用 [tableView dequeueReusableCellWithIdentifier:kAHCellIdentifier forIndexPath:indexPath]; 无效或者。

更短的问题

为什么 dequeueReusableCellWithIdentifier 返回nil,因此如果我在<$ c $中使用静态NSString,则使用 cell == nil 块中的UITableViewCellStyle启动单元格c> cellForRowAtIndexPath 方法调用,如果我使用上面定义的类级全局常量,则不行。

Why does the dequeueReusableCellWithIdentifier return nil and thus initiate the cell using the UITableViewCellStyle in the cell == nil block if I use a static NSString in the cellForRowAtIndexPath method call, and not, if I use a class level global constant as defined above.

附加

更多测试产生了一些不同的结果。如果你为单元格重用标识符注册一个类,然后在 cellForRowAtIndexPath 中给单元格一个不同的标识符,然后它就可以了。如果您给它与注册类名称相同,则它不能按预期工作。

Some more testing has yielded some different results. If you register a class for the cell reuse identifier and then give the cell a different identifier in cellForRowAtIndexPath then it works. If you give it the same name as the registered class, then it doesn't work as expected.

答案

经过一些测试和@ MANIAK_dobrii的回答,一些清晰度。

After some testing, and @MANIAK_dobrii's answer, some clarity.

如果你想使用更新的单元格出列方法 dequeueReusableCellWithIdentifier:forIndexPath 并且需要使用 UITableViewCellStyle 而不是默认值,你需要子类 UITableViewCell 并覆盖 initWithStyle 方法调用中的tableview样式。

If you want to use the newer cell dequeue method dequeueReusableCellWithIdentifier:forIndexPath and need to use a UITableViewCellStyle other than default, you'll need to subclass UITableViewCell and override the tableview style in the initWithStyle method call.

如果您愿意使用旧的方法然后确保你没有为重用标识符注册一个类,否则它将无法工作。

If you are happy to use the older method then make sure you don't register a class for the reuse identifier otherwise it will not work.

推荐答案

这很有趣,因为我刚刚在 dequeueReusableCellWithIdentifier的文档中找到了一个新的段落:我上次看到的时候没看到:

That's interesting, because I've just found a new paragraph in the docs for dequeueReusableCellWithIdentifier: I didn't see last time I was looking there:


如果您为t注册了一个类他指定了标识符,并且必须创建一个新的单元格
,此方法通过调用其
initWithStyle:reuseIdentifier:方法来初始化单元格。对于基于nib的单元格,此
方法从提供的nib文件加载单元格对象。如果
现有单元格可用于重用,则此方法将调用单元格的
prepareForReuse方法。

If you registered a class for the specified identifier and a new cell must be created, this method initializes the cell by calling its initWithStyle:reuseIdentifier: method. For nib-based cells, this method loads the cell object from the provided nib file. If an existing cell was available for reuse, this method calls the cell’s prepareForReuse method instead.

这意味着如果你注册一个类甚至 dequeueReusableCellWithIdentifier:将尝试创建单元格,如果它在重用队列中不可用并且总是返回一个有效的单元格?由于 -dequeueReusableCellWithIdentifier:forIndexPath:可用,我只使用它。所以,我的猜测是你的

Does this mean that if you register a class even dequeueReusableCellWithIdentifier: will try to create cell if it is not available in the reuse queue and always return a valid cell? Since -dequeueReusableCellWithIdentifier:forIndexPath: got available, I was using only it. So, my guess is that your

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}

永远不会被调用,你最终会得到通过

never get's called and you end up with cells created via

[[registred_class alloc] initWithStyle:STANDARD_STYLE reuseIdentifier:registred_reuse_identifier];

与此同时,你已经说过,你得到编译时间错误,如果你没有注册课程,这很奇怪,你不应该得到任何。

At the same time, you've stated, that you get compile time errors if you don't register class, that's strange, you should not get any.

所以,我的解决方案将是或:

1 。不要通过 -registerClass注册单元类:forCellReuseIdentifier:并使用 -dequeueReusableCellWithIdentifier:来获取重用的单元格或创建就像你现在正在做的那样。再次,使用oldschool方法,你不注册任何东西,只要有队列就出队,如果没有就创造。

So, my solution would be or:
1. Don't register cell class via -registerClass:forCellReuseIdentifier: and use -dequeueReusableCellWithIdentifier: to get reused cells or create them as you're doing it right now. Again, use oldschool approach, you don't register anything, just dequeue if there is and create if there is no.

// 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
// i.e. 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.创建笔尖,放置一个在那里的UITableViewCell,使它的样式为 UITableViewCellStyleSubtitle 并注册该nib以获取重用标识符而不是具有 registerNib的类:forCellReuseIdentifier:

or:
2. Create nib, put a UITableViewCell there, make it's style be UITableViewCellStyleSubtitle and register that nib for a reuse identifier instead of a class with registerNib:forCellReuseIdentifier:.

另外,请确保将所有标题/颜色/透明度设置为正确,这样您就不必将空字符串或nil设置为标签上的标签细胞。

Also, make sure, you set all the titles/colors/transparencies right, so that you don't just set empty string or nil to a label on a cell.

这篇关于tableView:dequeueReusableCellWithIdentifier与“global”相关的问题不变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆