Reputation: 691
I have a 5x5 grid of cells in a UICollectionView, each with an image set like this:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"circleCell" forIndexPath:indexPath];
imageArray = [[NSMutableArray alloc]init];
for (int i=1; i<=12; i++) {
UIImage *imageToAdd = [UIImage imageNamed:[NSString stringWithFormat:@"%i", i]];
[imageArray addObject:imageToAdd];
}
self.cellImageView = [[UIImageView alloc] initWithFrame:[self getCircleSize]];
int i = arc4random() % 12;
[self.cellImageView setImage:[imageArray objectAtIndex:i]];
[cell addSubview:self.cellImageView];
cell.tag = i;
return cell;
}
Each image is a circle of a random color - 1.png to 12.png. I am detecting taps on a specific cell, and then getting it's color and position in the collection view:
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
NSIndexPath *indexPath = [collectionView indexPathForCell:cell];
self.firstCircleSection = indexPath.section;
self.firstCircleRow = indexPath.row;
self.firstCircleIndex = (indexPath.section * 5) + (indexPath.row + 1);
self.firstCircleNum = (int)cell.tag;
//I have a dictionary with colors and keys, e.g 1 Yellow, 2 Blue, 3 Red. This line gets the color:
NSString *dotColor = [NSString stringWithFormat:@"Colour: %@", [self.colorDict objectForKey:[NSString stringWithFormat:@"%ld", self.firstCircleNum]]];
Then for the second circle tap of another circle, I am calculating what the new color of each circle will be (a color in the middle of the two selected colors):
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
NSIndexPath *indexPath = [collectionView indexPathForCell:cell];
self.secondCircleSection = indexPath.section;
self.secondCircleRow = indexPath.row;
self.secondCircleIndex = (indexPath.section * 5) + (indexPath.row + 1);
self.secondCircleNum = (int)cell.tag;
NSString *circleColor = [NSString stringWithFormat:@"Colour: %@", [self.colorDict objectForKey:[NSString stringWithFormat:@"%ld", self.secondCircleNum]]];
NSInteger i = (self.firstCircleNum + self.secondCircleNum)/2;
NSString *dotColor = [NSString stringWithFormat:@"Colour: %@", [self.colorDict objectForKey:[NSString stringWithFormat:@"%ld", i]]];
// Labels on the view for showing what the colors mix like
colorLabel2.text = circleColor;
positionLabel2.text = [NSString stringWithFormat: @"Position: %ld", self.secondCircleIndex];
mixedColorLabel.text = [NSString stringWithFormat:@"New %@", dotColor];
NSIndexPath *indexPath2 = [NSIndexPath indexPathForRow:self.firstCircleRow inSection:self.firstCircleSection];
NSInteger theFirstCircleIndex = (indexPath2.section * 5) + (indexPath2.row + 1);
NSIndexPath *indexPath3 = [NSIndexPath indexPathForRow:self.secondCircleRow inSection:self.secondCircleSection];
NSInteger theSecondCircleIndex = (indexPath3.section * 5) + (indexPath3.row + 1);
// Get a reference to the two cells
UICollectionViewCell *firstCircle = [collectionView dequeueReusableCellWithReuseIdentifier:@"circleCell" forIndexPath:indexPath2];
UICollectionViewCell *secondCircle = [collectionView dequeueReusableCellWithReuseIdentifier:@"circleCell" forIndexPath:indexPath3];
My question is, once I have done all this, how can I change the image of those two cells - firstCircle and secondCircle? I have a property on the custom CollectionViewCell, cellImage, but am unable to access it with: firstCircle.cellImage. I want to change the image on both cells.
Upvotes: 0
Views: 2471
Reputation: 21536
In your cellForItemAtIndexPath:
method, you are creating a new UIImageView
, setting its image from your array, and adding it as a subview of the cell. This is different from the cellImage
property of the cell. To fix this:
Either:
If you have configured your custom CollectionViewCell
in a storyboard (i.e. added an image view to the prototype cell, and hooked it up to the CollectionViewCell's cellImage
outlet), then you needn't add the extra UIImageView
you can just use:
cell.cellImage.image = [imageArray objectAtIndex:i];
Or: If it's not configured in a storyboard (or the CollectionViewCell initialiser), then keep your existing code, but set cell.cellImage to point to the imageView you created:
cell.cellImage = self.cellImageView;
Next:
In your other code (which I assume is in didSelectItemAtIndexPath
?), the following line tells the compiler that cells are of the base UICollectionViewCell
class:
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
But you want the compiler to know that these cells are actually your custom CollectionViewCell class. So amend the line to:
CollectionViewCell *cell = (CollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
(and similarly elsewhere). That done, the compiler should then let you use the cellImage
property without problem.
Now, to get a reference to the cells for indexPath2
and indexPath3
, don't use the dequeueReusableCellWithIdentifier:
method, use cellForItemAtIndexPath:
(just as you do in the first line):
CollectionViewCell *firstCircle = [collectionView cellForItemAtIndexPath:indexPath2];
CollectionViewCell *secondCircle = [collectionView cellForItemAtIndexPath:indexPath3];
You can then manipulate their images with firstCircle.cellImage.image
etc.
Also, there is some redundancy in your code: with these lines:
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
NSIndexPath *indexPath = [collectionView indexPathForCell:cell];
you are getting the cell for a given indexPath, and then getting the indexPath for that cell - it will be the same. So you can delete the second of these lines. Also, in the code which handles secondCircle
, indexPath3
is the same as indexPath
, and secondCircle
will actually be the cell
that you set at the start of the code. So just use:
CollectionViewCell *secondCircle = cell;
Finally, your cellForItemAtIndexPath
loads the imageArray every time it is called - which is unnecessary. I would use a different method to load these images - perhaps the viewDidLoad
method.
Upvotes: 2