7

我正在组合一个 TableView,我需要在同一个表中使用多个单元格类。

例如,我将如何在我的方法中使用多个单元类cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...

    return cell;
}

我知道我可以简单地UITableViewCell用我的自定义类替换并使用 if 语句来根据索引调整类,但这不是有点乱,什么是合理的,并且可能是最聪明的方法?

4

3 回答 3

9

当然可以。只需创建自定义单元的新实例并给它们一个新的 CellId。

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

   if (condition1)
    {
        static NSString *CellIdentifier1 = @"Cell1";
        UITableViewCell *cell = 
         [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];

        // TODO: if cell is null, create new cell of desired type.  
        // This is where you    create your custom cell that is 
        // derived form UITableViewCell.
    }
    else
    {
        static NSString *CellIdentifier2 = @"Cell2";
        UITableViewCell *cell = 
         [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];

        //TODO: if cell is null, create new cell of desired type

    }
    // Configure the cell...

    return cell;
}
于 2012-07-25T22:06:13.193 回答
8

您可以通过将表格定义为在其 .xib 文件或 Storyboard 中包含多个原型单元格来实现此目的。请注意下面 Xcode 屏幕截图中表格视图的“动态原型”设置:

在此处输入图像描述

每个原型单元必须被赋予一个唯一的重用标识符。在这个例子中,第一个单元格类型有一个重用标识符@"ScanCell",第二个@"DetailCell"。然后,在您的-tableView:cellForRowAtIndexPath:方法中,您只需通过选择传递给的重用标识符来选择要使用的单元格类别-dequeueReusableCellWithIdentifier:

这是从我自己的一个应用程序中获取的示例:

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString * cellIdentifier = @"DetailCell";
    if ([indexPath section] == 0) {
        cellIdentifier = @"ScanCell";
    }
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier
                                                             forIndexPath:indexPath];
    if ([indexPath section] == 1) {
        CBPeripheral * peripheral = (CBPeripheral *)[self.appDelegate.peripherals objectAtIndex:[indexPath row]];
        cell.textLabel.text = [peripheral name];
        cell.detailTextLabel.text = [self.appDelegate.peripheralKeys objectAtIndex:[indexPath row]];
    }
    return cell;
}

如果您希望原型单元具有不同的类,只需在 .xib 或 Storyboard 文件中设置它们的类。

于 2012-07-25T22:05:36.273 回答
3

在某些时候,您需要将不同的单元格类与数据源中的不同项目类型相关联。if声明可能是要走的路。您可以将其封装在一个单独的方法中,如下所示:

+(Class)cellClassForItem:(id)rowItem
{
    Class theClass = [ UITableViewCell class ] ;

    if ( [ rowItem isKindOfClass:[ ... class ] ] )
    {
        theClass = [ CellClass1 class ] ;
    }
    else if ( [ rowItem isKindOfClass:[ ... class ] ] )
    {
        theClass = [ CellClass2 class ] ;
    }

    return theClass ;
}

或者,您可能让数据源中的每个项目都实现一个protocol

@protocol DataSourceItem <NSObject>
-(Class)tableViewCellClass ;
@end

现在,您的委托方法看起来像这样(假设第二种技术)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id<DataSourceItem> item = (id<DataSourceItem>)[ tableView itemForRowAtIndexPath:indexPath ] ;
    Class cellClass = [ item tableViewCellClass ] ;
    NSString * cellID = NSStringFromClass( cellClass ) ;

    UITableViewCell *cell = [ tableView dequeueReusableCellWithIdentifier:cellID ] ;
    if ( !cell )
    {
        cell = [ [ cellClass alloc ] initWithStyle:... reuseIdentifier:cellID ] ;
    }

    cell.value = item ;

    return cell;
}
于 2012-07-25T22:06:51.447 回答