Question

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;
}
Was it helpful?

Solution 2

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;

OTHER TIPS

The problem is simply that the compiler only knows that cell Is a UICollectionViewCell * and that type doesn't have a property x. So, you need to give the compiler the information it needs. One way is to derive both your cell types from some common superclass that includes a property x, and then use that type for your cell ivar. A simpler way is to declare a protocol with that property, and the adopt that protocol in your cell types. Then you can simply specify the cell as a standard cell that adopts that protocol, like this:

 UICollectionViewCell<MyProperty> *cell;

You have declared cell as a UICollectionViewCell which does not have the property x. The object oriented thing to do would be to create an abstract subclass of UICollectionViewCell that declares property x. Then your TaskCollectionCell and PeopleCollectionCell can subclass this class. You would then declare cell to be of this type of class.

If you have created an instance on cell of the class UICollectionViewCell but when you do cell.x you still get an error, it could be that the class of the object cell does not have the x field or it is not accessible from that scope.

I have the field declared on a subclass and still doesn't work, why?

Suppose you have a base class called Person and then a subclass called Children.

If you declare a variable of type Person and store a Children object on it, you can't access Children's fields that aren't declared on Person. It is a principle of the object paradigm.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top