如何使用动态重用标识符设置和出列自定义 UITableViewCell?

Posted

技术标签:

【中文标题】如何使用动态重用标识符设置和出列自定义 UITableViewCell?【英文标题】:How to set and dequeue custom UITableViewCell with dynamic reuse identifier? 【发布时间】:2012-11-14 01:01:25 【问题描述】:

这就是我最终想要做的事情。我想在 UITableView 中动态显示项目菜单,以便显示的项目类型确定加载的自定义单元格视图。例如,假设菜单项类型是“switch”,那么它将加载一个名为“switch.xib”的 nib,并且状态将根据该特定菜单项的值打开/关闭。可能有 5 个项目是“开关”类型,但值不同。所以我想为每一个使用相同的 xib,但 5 个实例。

所以,这个问题还有很长的路要走。当我从笔尖加载单元格视图时,我认为它需要唯一的重用标识符用于出队,以便在屏幕上回滚时,对吗? (每个实例都是唯一的,即每个菜单项。)在 Interface Builder 的 UITableViewCell 中,我看到可以在哪里设置重用标识符属性,但我想在运行时为开关的每个实例设置它。例如,菜单项#1 是一个开关,#2 是一个文本字段,#3 是一个开关,等等。所以 #1 和 #3 都需要唯一的单元格 ID 才能出列。

这是我的 cellForRowAtIndexPath 的样子:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

// Cells are unique; dequeue individual cells not generic cell formats
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", indexPath.row];

ITMenuItem *menuItem = [menu.menuItems objectAtIndex:indexPath.row];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) 
    // Load cell view from nib
    NSString *cellNib = [NSString stringWithFormat:@"MenuCell_%@", menuItem.type];
    [[NSBundle mainBundle] loadNibNamed:cellNib owner:self options:nil];
    cell = myCell;
    self.myCell = nil;

// Display menu item contents in cell
UILabel *cellLabel = (UILabel *) [cell viewWithTag:1];
[cellLabel setText:menuItem.name];
if ([menuItem.type isEqualToString:@"switch"]) 
    UISwitch *cellSwitch = (UISwitch *) [cell viewWithTag:2];
    [cellSwitch setOn:[menuItem.value isEqualToString:@"YES"]];

else if ([menuItem.type isEqualToString:@"text"]) 
    UITextField *textField = (UITextField *) [cell viewWithTag:2];
    [textField setText:menuItem.value];


return cell;

【问题讨论】:

您的问题是什么?你有什么问题?什么错误信息? 对不起,说清楚可能有点困难。问题是,如何在分配单元格时使用重用标识符标记单元格,以便出队起作用? 【参考方案1】:

您可以在 nib 文件中设置重用标识符。因此,对于 switch.xib,您将使用 'switch' 作为重用标识符。那就换吧

NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", indexPath.row];

NSString *CellIdentifier = menuItem.type;

假设menuItem.type 是“开关”

【讨论】:

正确,menuItem.type 是 'switch'、'text' 等。问题是它的各个实例没有唯一性;假设我在同一个菜单中有 5 个“切换”菜单项,这不是问题吗?也许不会,也许我想多了。 是的,这正是您想要的。具有相同的重用标识符意味着“开关”单元的一个实例可以被另一个开关重用。 在我的情况下,少量的菜单项似乎可以正常工作,而不会增加内存使用量,根本不会使单元格出列。我不知道如果它尝试显示多个“切换”单元格是否会导致问题,例如,一次在屏幕上显示。可能不会,因为唯一的出队将是从屏幕上滚动出来的单元格。由于菜单不长,反正不会有太多的排队。感谢您的提示!【参考方案2】:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *cellIdentifier = @"Cell";
    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if(cell == nil)
    
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    
    TextFieldFormElement *item = [self.formItems objectAtIndex:indexPath.row];
    cell.labelField.text = item.label;
    return cell;

【讨论】:

是否可以从 xib 加载它?【参考方案3】:

对于我的想法,如果您的类型不是太多,请在不同的 xib 和 swift 文件中设计每个单元格。主要针对性能问题。

如果不能出队,给他们不同的标识符。您可以为 tableview 或 collection view 注册多个标识符(我们的一个应用程序以这种方式使用 12 个不同的单元格。)

但是这样处理 IBAction 会有点麻烦。

【讨论】:

【参考方案4】:

您可以通过这样的方式加载来自 xib 文件的自定义单元格。 xib文件名与cell类名和reuse id一致。

- (YourCell *)tableView:(UITableView *)_tableView getCellWithId:(NSString *)cellId

        YourCell *cell;

        /* Cell id and xib have the same name. */
        cell = [_tableView dequeueReusableCellWithIdentifier:cellId];
        if (cell == nil) 
                NSArray *nib = [[NSBundle mainBundle] loadNibNamed:cellId owner:self options:nil];
                cell = [nib objectAtIndex:0];
        
        return cell;

【讨论】:

以上是关于如何使用动态重用标识符设置和出列自定义 UITableViewCell?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在制作自定义表格视图单元格时将可重用单元格出列两次

表视图出列可重用单元格重叠

从可重用单元中出列时,自定义 CollectionViewCell 上会触发啥方法?

自定义表格单元重用/出列

在运行时重用具有动态布局内容的单元格

动态设置可重用 tableViewCell 的标识符