简体   繁体   中英

Returning multiple UITableViewCell subclasses from cellForRowAtIndexPath?

I am looking to return a number of custom UITableViewCells depending on the type of object I get back from my savedGames array stored in my dataModel . My question is, am I going about this the right way? I have not done this before and just wanted to make sure I was on the right track an not missing something obvious.

Note: new cells are alloc-ed and init-ed elsewhere, that is why that is not shown in the code below.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger row = [indexPath row];
    SharedDataModel *dataModel = [SharedDataModel sharedInstance];
    id genericGameAtRow = [[dataModel savedGames] objectAtIndex:row];

    if([genericGameAtRow isMemberOfClass:[GameZoneOne class]]) {
        CellZoneOne *cell = [tableView dequeueReusableCellWithIdentifier:@"ZONEONE_ID"];
        return cell;
    }

    if([genericGameAtRow isMemberOfClass:[GameZoneTwo class]]) {
        CellZoneTwo *cell = [tableView dequeueReusableCellWithIdentifier:@"ZONETWO_ID"];
        return cell;
    }
    return nil;
}

EDIT: Quick question is returning nil at the bottom useful, I know it avoids the method not having a return value, but if none of the "if"s fire your going to get a "Must return a cell" error. Obviously its important to cover all the possible options, but would the final return not be better to return a default (vanilla) UITableViewCell instead? ... just curious.

Yes this is a correct solution.

Personally I would stay away from -[id<NSObject> isKindOfClass:] , since it generally is a sign of bad architecture. Instead I would have added a gameZone property to all possible classes in the savedGames array. And explicitly asked for it's zone/type.

The code you show is ok, and is the right way to go.

I'm quite new to this so I might be wrong, but wouldn't it be better if each item in your array used to build the uitableview had it's own property to build the cell?

So you could do something like

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
int row = [indexPath row];
[_myArray[row] formatCellAndSetData];

or maybe even

return [_myArray[row] buildCell];

Each of your custom uitableviewcell classes would all have the same method formatAndSetData but each could implement it differently. That way there's no dependency on:

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

as the dependency is injected in from your custom class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM