我正在组装一个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语句根据索引调整类,但不是有点混乱,什么是合理的,可能是最大的聪明的方式这样做?
答案 0 :(得分: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;
}
答案 1 :(得分:6)
您可以通过将表定义为在其.xib文件或Storyboard中包含多个原型单元格来完成此操作。请注意以下Xcode屏幕截图中表格视图的“Dynamic Prototypes”设置:
必须为每个原型单元提供唯一的重用标识符。在此示例中,第一个单元格类型具有重用标识符@"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文件中设置它们的类。
答案 2 :(得分: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;
}