Multiple UITableViewCell Classes in One UITableView?

匿名 (未验证) 提交于 2019-12-03 08:44:33

问题:

I am putting together a TableView and I need to have multiple cell classes used in the same table.

So for example how would I use more than one cell class in my cellForRowAtIndexPath method?

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

I know I could simply replace UITableViewCell with my custom class and use if statements to adjust the class depending on the index, but isn't that a bit messy, what would be a reasonable, and possibly the most intelligent way of doing this?

回答1:

Sure can. Just create new instances of your custom cells and give them a new 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; } 


回答2:

You can do this by defining the table to have several prototype cells in its .xib file or Storyboard. Note the setting "Dynamic Prototypes" for the table view in the Xcode screen shot below:

Each prototype cell must be given a unique reuse identifier. In this example, the first cell type has a reuse identifier @"ScanCell", and the second @"DetailCell". Then, in your -tableView:cellForRowAtIndexPath: method you simply choose which class of cell to use by choosing which reuse identifier you pass to -dequeueReusableCellWithIdentifier:.

Here is an example taken from one of my own apps:

- (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; } 

If you want the prototype cells to have different classes, simply set their class in the .xib or Storyboard file.



回答3:

At some point you will need to associate different cell classes with the different item types in your data source. An if statement might be the way to go. You might encapsulate this in a separate method, like this:

+(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 ; } 

Or, you might have each item in your data source implement a protocol:

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

Now, your delegate method would look like this (assuming the second technique)

- (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; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!