Im having a problem with my UICollectionView
. Initially it displays fine, showing a grid of cells, each cell with a single UIImageView
. These UIImageViews
are showing PNGs with transparency that are stored in the app's bundle.
My problem is, once the UICollectionView
has been scrolled, some of the cells seem to be corrupt.
A corrupt cell shows multiple images stacked on top of each other, the top most image is the one it should be showing, and images underneath are the ones that should be used in other cells.
My best guess is that this has something to do with the way cells inside a UICollectionView
are reused, but I am open to suggestions.
This is the delegate code I use for creating cells within the UICollectionView
:
// creates the individual cells to go in the menu view
- (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// create collection view cell
UICollectionViewCell * cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
// create a uiview where we can place all views that need to go into this cell
UIView * contents=[[UIView alloc] initWithFrame:cell.contentView.bounds];
[contents setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:contents];
// add a button image
NSString * buttonPath=[[NSBundle mainBundle] pathForResource:@"button" ofType:@"png" inDirectory:[[buttons objectAtIndex:indexPath.row] objectForKey:@"name"]];
UIImage * button=[UIImage imageWithContentsOfFile:buttonPath];
UIImageView * buttonView=[[UIImageView alloc] initWithImage:button];
[buttonView setContentMode:UIViewContentModeScaleAspectFit];
[buttonView setFrame:contents.bounds];
[contents addSubview:buttonView];
// set tag to the indexPath.row so we can access it later
[cell setTag:indexPath.row];
// add interactivity
UITapGestureRecognizer * tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onButtonTapped:)];
[tap setNumberOfTapsRequired:1];
[cell addGestureRecognizer:tap];
// return the cell
return cell;
}
I can provide more code if required.
How can I stop the cells from corrupting?
For anyone who is adding UICollectionView programmatically and have a custom cell, in other words no XIB file, then you have to add this line to viewDidLoad
For those who are looking for a Swifty answer, add this function to your
CustomCell
class:This is for removing duplicate text from label in uicollectionviewcell.
Right after
Just add this line,
The problem is that you keep adding views to the
UICollectionViewCell
as they are being reused automagically by theUICollectionView
. So the oldUIImageView
's are still on the cell as you are adding one more as thecellForItemAtIndexPath:
is called.DO NOT USE
addSubview:
!Instead you could make a custom cell with all the views you want already in them. So that when the
cellForItemAtIndexPath:
is called you only need to set the contents of this CustomCollectionViewCell instead.This way it will certainly stop being corrupted.
How to build a CustomCell.
Step1: Create the .h & .m class.
CustomCell.h
CustomCell.m
Step2: Import it! Now that we created the CustomCell we can import it in the class we want to use it in.
Step3: Use it in action!
Step4: Register the cell to the collectionView
in the viewDidLoad / loadView add this line:
Step5: Enjoy! Your CustomCell is done. Now do whatever you like and don't forget to get some coffee too.
That Happen because you add every time a
UIImageView
to your cell for fix this problem you have to Make a custom cell and then use it like take:Custom.h
Custom.m
Your Controller
You have also to set 'CustomCell' like Identifier to the Cell in IB