Search code examples
iosobjective-cuicollectionviewcellsubclassing

iOS return different subclass


I have a question about the following code:

 UICollectionViewCell *cell;

if (_peopleNotTasks == NO) {
    static NSString *CellIdentifier = @"TaskCollectionCell";
     cell = (TaskCollectionCell *)[cv dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
} else {
    static NSString *CellIdentifier = @"PeopleCollectionCell";
     cell = (PeopleCollectionCell *)[cv dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
}
//both cells have property x
//this does not work: 
cell.x = @"this is an awesome string";

return cell;

Why does that NOT work?

Both TaskCollectionCell and PeopleCollectionCell are subclasses of UICollectionViewCell.

Expected:

Access to the properties of TaskCollectionCell and PeopleCollectionCell.

If I make an outlet in the abstract class (which now is the superclass of TaskCollectionCell and PeopleCollectionCell) I cannot connect it? enter image description here

EDIT found a way to find the outlet of the parent (abstract) subclass:

enter image description here

EDIT Implemented solution with parent subclass:

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
 ParentCell *cell;
if (_onlyUsersTasks == NO) {
    static NSString *CellIdentifier = @"TaskCollectionCell";
    cell = (TaskCollectionCell *)[cv dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
} else {
    static NSString *CellIdentifier = @"PeopleCollectionCell";
    cell = (PeopleCollectionCell *)[cv dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
}
cell.commonString = @"Thanks Jonathan";
return cell;
}

Solution

  • You are declaring the cell as a UICollectionViewCell, which does not have an x property. You are also casting the instance of the cell to your custom class, but the cell variable is still declared as a UICollectionViewCell. Instead, you could create a super class for TaskCollectionCell and PeopleCollectionCell, which declares the x property.

    E.g.

    NSString * const PeopleCollectionCellIdentifier = @"PeopleCollectionCell"; 
    NSString * const TaskCollectionCellIdentifier = @"TaskCollectionCell";
    
    CustomSuperClass * cell = (self.arePeopleNotTasks) ? [cv dequeueReusableCellWithReuseIdentifier:PeopleCollectionCellIdentifier forIndexPath:indexPath] : [cv dequeueReusableCellWithReuseIdentifier:TaskCollectionCellIdentifier forIndexPath:indexPath];
    
    cell.x = @"this is an awesome string";
    
    
    if ([cell.reuseIdentifier isEqualToString:PeopleCollectionCellIdentifier])
    {
        PeopleCollectionCell * peopleCollectionCell = (PeopleCollectionCell *)cell;
        peopleCollectionCell.peopleOnlyProperty = nil;
    }
    else if ([cell.reuseIdentifier isEqualToString:TaskCollectionCellIdentifier])
    {
        TaskCollectionCell * taskCollectionCell = (TaskCollectionCell *)cell;
        taskCollectionCell.taskOnlyProperty = nil;
    } 
    return cell;