UICollectionView : two columns - ios

I have a collectionview that will be a menu with two columns, without spacing: so each cell with width 160. And I need a line separating each cell.
Each cell contains an imageview and a label.
I'm trying to add a line separator between the cells like this: How to add views between UICollectionViewCells in a UICollectionView?
But the result is:
Code:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0);
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return 2;
}
// 2
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return [options count];
}
// 3
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"MenuOptionCell";
UICollectionViewCell *cell = [self.menu dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *img = (UIImageView*) [cell viewWithTag:100];
UILabel *lbl = (UILabel*) [cell viewWithTag:90];
UIView *seperatorView = [[UIView alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+cell.frame.size.height, cell.frame.size.width-10, 1)];
seperatorView.backgroundColor = [UIColor whiteColor];
[self.menu addSubview:seperatorView];
[self.menu bringSubviewToFront:seperatorView];
UIView *seperatorView2 = [[UIView alloc] initWithFrame:CGRectMake(cell.frame.origin.x+cell.frame.size.width-10, cell.frame.origin.y, 1, cell.frame.size.height)];
seperatorView.backgroundColor = [UIColor whiteColor];
[self.menu addSubview:seperatorView2];
[self.menu bringSubviewToFront:seperatorView2];
lbl.text = #"TEST";
img.image = [UIImage imageNamed:#"test.png"];
return cell;
}

Related

Application crash when set header of UICollectionView horizontally

I am pretty new in UICollectionView. And I am really tired to find out the solution. I am trying to add Header in 3 Horizontally Row. I am using Collection view flow layout.
Here is my code which I implement:
- (void)awakeFromNib {
self.collectionView.backgroundColor = [UIColor colorWithRed:204.0/255.0 green:204.0/255.0 blue:204.0/255.0 alpha:1.0];
self.collectionView.backgroundColor = [UIColor clearColor];
self.collectionView.backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
flowLayout.itemSize = CGSizeMake(130.0, 170.0);
[self.collectionView setCollectionViewLayout:flowLayout];
// Register the colleciton cell
[_collectionView registerNib:[UINib nibWithNibName:#"ORGArticleCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"ORGArticleCollectionViewCell"];
[self.collectionView registerClass:[_HeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"HeaderView"];
}
#pragma mark - UICollectionViewDataSource methods
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (section == 0) {
return [self.collectionData count];
}
else if(section == 1)
{
return [self.collectionData1 count];
}
else
{
return [self.collectionData2 count];
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ORGArticleCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"ORGArticleCollectionViewCell" forIndexPath:indexPath];
cell.articleTitle.text = [self.collectionData objectAtIndex:[indexPath row]];
NSString *URL = [self.collectionImageData objectAtIndex:indexPath.row];
[cell.articleImage setImageWithURL:[NSURL URLWithString:URL] placeholderImage:[UIImage imageNamed:#"profile-image-placeholder"]];
cell.articleImage.contentMode = UIViewContentModeScaleToFill;
cell.articlePrice.text = [self.collectionDataPric objectAtIndex:[indexPath row]];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *cellData = [self.collectionData objectAtIndex:[indexPath row]];
[[NSNotificationCenter defaultCenter] postNotificationName:#"didSelectItemFromCollectionView" object:cellData];
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 0;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:
UICollectionElementKindSectionHeader withReuseIdentifier:#"HeaderView" forIndexPath:indexPath];
UILabel *label = (UILabel *)[headerView viewWithTag:10];
if (!label) {
label = [[UILabel alloc] initWithFrame:CGRectInset(headerView.bounds, 5, 5)];
label.tag = 10;
label.font = [UIFont boldSystemFontOfSize:12];
label.textColor = [UIColor darkGrayColor];
[headerView addSubview:label];
}
label.text = [NSString stringWithFormat:#"Section %d", indexPath.section];
return headerView;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
CGSize headerSize = CGSizeMake(320, 44);
return headerSize;
}
My App crash in viewForSupplementaryElementOfKind method when I initialize the header view.
Following are the crash log:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no UICollectionViewLayoutAttributes instance for -layoutAttributesForSupplementaryElementOfKind: UICollectionElementKindSectionHeader at path {length = 2, path = 0 - 0}'
The problem with your code is [headerView addSubview:label]; this is called only when label is equal to nil. but you have to call this statement every time when viewForSupplementaryElementOfKind is called.
Update your viewForSupplementaryElementOfKind function with following code.
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:
UICollectionElementKindSectionHeader withReuseIdentifier:#"HeaderView" forIndexPath:indexPath];
UILabel *label = (UILabel *)[headerView viewWithTag:10];
if (!label) {
label = [[UILabel alloc] initWithFrame:CGRectInset(headerView.bounds, 5, 5)];
label.tag = 10;
label.font = [UIFont boldSystemFontOfSize:12];
label.textColor = [UIColor darkGrayColor];
}
label.text = [NSString stringWithFormat:#"Section %d", indexPath.section];
[headerView addSubview:label];
return headerView;
}

UICollectionView Headers Overlapping

I have a collectionView with the following relevant methods:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath {
if (kind == UICollectionElementKindSectionHeader) {
Scoreboard *thisScoreboard = [self.scoreboards objectAtIndex:indexPath.section];
ScoreboardReusableView *view = nil;
view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:#"scoreboardHeader"
forIndexPath:indexPath];
//view.backgroundColor = [UIColor yellowColor];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
//label.text = [NSString stringWithFormat:#"%# vs %#", thisScoreboard.awayteam, thisScoreboard.hometeam];
label.text = [NSString stringWithFormat:#"%ld", (long)indexPath.section];
[view addSubview:label];
return view;
}
return nil;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeMake(self.view.frame.size.width, 34);
}
However, the label text is overlapping. Here are two screenshots of the collectionView. Sections 0 and 1 (notice how the text does NOT overlap):
And sections 2 and 3 (the text overlaps here and on all subsequent section headers):
My header xib ScoreboardReusableView is COMPLETELY blank because no matter what I put in it (e.g., a UILabel or a UIImageView, it would not show up in the UICollectionView Header). Preferably I would design the header in a xib, but since that's not working I tried to do it programmatically, but now labels are overlapping.
Collection views re-use cells and headers. When a header is scrolled offscreen it is added to a queue, and will be re-used for the next header to be scrolled onscreen. That means your configuration code in collectionView:viewForSupplementaryElementOfKind: method will be run again on the same header view at different indexPaths. Since you're just adding a label every time your configuration code runs, they will stack one on top of the other.
The correct approach is to have a label property on the headerView, so that its text can be changed. But...
no matter what I put in it (e.g., a UILabel or a UIImageView), it would not show up
This is your real issue. Do you have autolayout enabled on the xib? If so be sure to add constraints for the label, otherwise it will have zero width and height, giving the effect you describe.
Swift 3 version, hope it helps
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
var reusableview: UICollectionReusableView?
reusableview = nil
reusableview = playersCollectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "collViewHeader", for: indexPath as IndexPath)
if kind == UICollectionElementKindSectionHeader {
//remove all previous subviews:
if let views = reusableview?.subviews {
for view in views {
view.removeFromSuperview()
}
}
//----------
if reusableview == nil {
reusableview = UICollectionReusableView.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 50))
}
//init label
let label = UILabel.init(frame: CGRect(x: 10.0, y: 20.0, width: self.view.frame.width-20, height: 25.0)) //-20 from width to make it no go out of screen bounds
label.textColor = UIColor.blue //you may set your color here :)
label.adjustsFontSizeToFitWidth = true
label.text = "your text here"
reusableview?.addSubview(label)
}
return reusableview!
}
ScoreboardReusableView is blank but it was reusable. You must put UILabel into header xib and set text for it after that.
For example:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
if (kind == UICollectionElementKindSectionHeader) {
Scoreboard *thisScoreboard = [self.scoreboards objectAtIndex:indexPath.section];
ScoreboardReusableView *view = nil;
view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:#"scoreboardHeader"
forIndexPath:indexPath];
view.label.text = [NSString stringWithFormat:#"%ld", (long)indexPath.section];
return view;
}
return nil;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionReusableView *reusableview=nil;
reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"HeaderView" forIndexPath:indexPath];
NSArray *viewsToRemove = [reusableview subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
if (reusableview==nil) {
reusableview=[[UICollectionReusableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 30)];
}
reusableview.backgroundColor=[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0];
UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(10, 0, [UIScreen mainScreen].bounds.size.width-90, 30)];
[lblTitle setFont:[UIFont fontWithName:#"Ubuntu-Light" size:12]];
lblTitle.textColor=HTAtHomeColor;
[reusableview addSubview:lblTitle];
UILabel *lblCount=[[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width-80, 0, 70, 30)];
lblCount.textAlignment=NSTextAlignmentRight;
lblCount.textColor=[UIColor blackColor];
[lblCount setFont:[UIFont fontWithName:#"Ubuntu-Light" size:12]];
lblCount.text=[NSString stringWithFormat:#"%d Section Header",indexPath.row];
[reusableview addSubview:lblCount];
return reusableview;
}
return nil;
}

iOS: Not full frame of UICollectionViewCell is tappable/clickable

I created a UIView with a UICollectionView, and that UIView is added on a UIViewController. UIViewController using the delegate (photoDidTapped) of that UIView to determine is something was clicked/tapped. First row, is okay, means whole cell area is tappable. Second row, horizontal half of that is clickable. 3rd row, almost 10% horizontal of the cell is clickable and so on.
Code:
- (UICollectionView *)collectionView
{
if (!_collectionView) {
UICollectionViewFlowLayout *flowLayout=[[UICollectionViewFlowLayout alloc] init];
flowLayout.itemSize = CGSizeMake(THUMB_DIMENSION, THUMB_DIMENSION);
[flowLayout setMinimumInteritemSpacing:0.0f];
[flowLayout setMinimumLineSpacing:PHOTO_MARGIN];
_collectionView = [[UICollectionView alloc] initWithFrame:self.frame collectionViewLayout:flowLayout];
_collectionView.frame = CGRectMake(0, 0, SCREEN_WIDTH, self.frame.size.height);
_collectionView.backgroundColor = [UIColor clearColor];
_collectionView.delegate = self;
_collectionView.dataSource = self;
_collectionView.allowsSelection = YES;
_collectionView.alwaysBounceVertical = YES;
_collectionView.scrollEnabled = NO;
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
}
return _collectionView;
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return (_photos.count > 9 ? 9 : _photos.count);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath; {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height)];
imgView.clipsToBounds = YES;
imgView.backgroundColor = RGB(250, 250, 250);
if (_photos.count) {
PhotoDM *photo = [_photos objectAtIndex:indexPath.row];
[imgView setImageWithURL:[NSURL URLWithString:photo.largeLink]
placeholderImage:[UIImage imageNamed:#"placeholder"]];
}
[cell addSubview:imgView];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"tapped: %ld", (long)indexPath.row);
if([delegate respondsToSelector:#selector(photoDidTapped:)])
[delegate performSelector:#selector(photoDidTapped:) withObject:[[NSNumber alloc] initWithInteger:indexPath.row] ];
}
Your code contains 2 problems.
1. If you create a subview, you should use self.bounds.
2. The view can be resized, after UICollectionView has been added. It means that you should configure autoresizingMask or NSLayoutConstrans. (UICollectionView can be out of view's bounds).
To debug this problem, you can create different background colors for the view, the collectionView, the viewController's view.

Customizing UICollectionViewCell depending on indexPath

Hi i'm trying to customize my collectionviewcell depending on its indexPath but also if I set
if (indexPath.row == 0)
{
[cell addSubView: view];
}
the view appear random in some cells.
This is the code I'm using
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 15;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
NSInteger row = indexPath.row;
UIView *contentCell = [[UIView alloc] initWithFrame:cell.frame];
if (row == 0)
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(1.0f, 1.0f, 50.0f, 50.0f)];
label.text = #"Test";
[contentCell addSubview:label];
}
[cell addSubview:contentCell];
cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"container"]];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%d", indexPath.row);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(414, 228);
}
You have to read about reusable cells.
you can avoid the problem for now by doing this.
if (row == 0)
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(1.0f, 1.0f, 50.0f, 50.0f)];
label.text = #"Test";
label.tag = 200;
[contentCell addSubview:label];
}else{
UIView* lbl = [contentCell viewWithTag:200];
if(lbl)
[lbl removeFromSuperView];
}
but this will affect the scrolling and memory performance, you can put the label in the cell by default && show/hide it in the if/else blocks
You are adding view several times as a subview. Cells are reused due to "dequeueReusableCellWithReuseIdentifier", so after you scroll up and down, you get back existing view, which already has subview added.
You should read more about reusing cells.
One way to avoid that behavior is to create all views when you create a cell and just show / hide them.
Otherwise create cells with different identifier for different rows - in your case for row 0.

Reusability issue on UICollectionView

I had worked with UITableView but I have never ever use of UICollectionView in my apps. So I want to create UICollectionView programmatically.
Following is my code:
UICollectionViewFlowLayout *layout =[[UICollectionViewFlowLayout alloc] init];
_collectionView=[[UICollectionView alloc] initWithFrame:CGRectMake(0, 43, self.view.frame.size.width, self.view.frame.size.height - 84) collectionViewLayout:layout];
[_collectionView setDataSource:self];
[_collectionView setDelegate:self];
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
layout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5);
layout.minimumInteritemSpacing = 5;
[_collectionView setBackgroundColor:self.view.backgroundColor];
[self.view addSubview:_collectionView];
Delegate and Datasource methods.
#pragma mark -
#pragma mark - UITableView Delegate Methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 15;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
if (cell.selected)
cell.backgroundColor = [UIColor lightGrayColor]; // highlight selection cell
else
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background-grid.png"]]; // Default Cell
UIImageView *imgPhoto = [[UIImageView alloc] init];
imgPhoto.userInteractionEnabled = YES;
imgPhoto.backgroundColor = [UIColor grayColor];
imgPhoto.frame = CGRectMake(3.5, 5, 90, 80);
imgPhoto.clipsToBounds = YES;
imgPhoto.image = [UIImage imageNamed:#"product.png"];
[cell.contentView addSubview:imgPhoto];
UILabel *lblCategoryTitle = [[UILabel alloc] init];
[lblCategoryTitle setFont: [UIFont fontWithName:#"OpenSans-Bold" size:14]];
lblCategoryTitle.textAlignment = NSTextAlignmentCenter;
lblCategoryTitle.frame = CGRectMake(3.5, 90, 90, 24);
lblCategoryTitle.textColor = [UIColor blackColor];
lblCategoryTitle.text = #"Product 1";
lblCategoryTitle.backgroundColor = [UIColor clearColor];
lblCategoryTitle.numberOfLines = 2;
[cell.contentView addSubview:lblCategoryTitle];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(97, 118);
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *datasetCell =[collectionView cellForItemAtIndexPath:indexPath];
datasetCell.backgroundColor = [UIColor lightGrayColor]; // highlight selection
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *datasetCell =[collectionView cellForItemAtIndexPath:indexPath];
datasetCell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background-grid.png"]]; // default cell
}
Then my screen Look like
Question 1 - Look at above screen, you will see that 1st and 3rd item is looking blur (see Product 1 ) then 2nd/middle item ? why this is happening ?
And whenever I scroll up/down UICollectionView then items are overwrite, Look at Next image
After looked this image, from my experience of UITableView, it's happening because of Reusability of cell of UICollectionView.
Question 2 - Then how can i solve it?
Please give my your suggestion and help me on this issue.
EDITED: (suggestion of #Dima)
Custom cell
.h file
#import <UIKit/UIKit.h>
#interface customeGridCell : UICollectionViewCell
#property (nonatomic, strong) UIImageView *imgPhoto;
#property (nonatomic, strong) UILabel *lblCategoryTitle;
#end
.m file
#import "customeGridCell.h"
#implementation customeGridCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.imgPhoto = [[UIImageView alloc] init];
self.imgPhoto.userInteractionEnabled = YES;
self.imgPhoto.backgroundColor = [UIColor grayColor];
self.imgPhoto.frame = CGRectMake(3.5, 5, 90, 80);
[self addSubview:self.imgPhoto];
self.lblCategoryTitle = [[UILabel alloc] init];
[self.lblCategoryTitle setFont: [UIFont fontWithName:#"OpenSans-Bold" size:14]];
self.lblCategoryTitle.textAlignment = NSTextAlignmentCenter;
self.lblCategoryTitle.frame = CGRectMake(3.5, 90, 90, 24);
self.lblCategoryTitle.textColor = [UIColor blackColor];
self.lblCategoryTitle.backgroundColor = [UIColor clearColor];
self.lblCategoryTitle.numberOfLines = 2;
[self addSubview:self.lblCategoryTitle];
}
return self;
}
And code of cellForItemAtIndexPath
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
customeGridCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
if (cell.selected)
cell.backgroundColor = [UIColor lightGrayColor]; // highlight selection cell
else
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background-grid.png"]]; // Default Cell
cell.imgPhoto.image = [UIImage imageNamed:#"product.png"];
cell.lblCategoryTitle.text = #"Product 1";
return cell;
}
The problem is in your collectionView:cellForItemAtIndexPath: method. You are adding those subviews every single time a cell is reused, on top of each other.
You should create a UICollectionViewCell subclass and add all of the extra subviews you want into its initializer. This will make sure they only get added once.
sample code:
Here is an example of how you would subclass UICollectionViewCell
#interface MyCustomCell : UICollectionViewCell
#property (nonatomic, strong) UILabel *customLabel;
#property (nonatomic, strong) UIImageView *customImageView;
#end
// in implementation file
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// initialize label and imageview here, then add them as subviews to the content view
}
return self;
}
Then when you are grabbing a cell you just do something like:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
if (cell.selected)
cell.backgroundColor = [UIColor lightGrayColor]; // highlight selection cell
else
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background-grid.png"]]; // Default Cell
cell.customImageView.image = // whatever
cell.customLabel.text = // whatever
return cell;
}
You can do it with two way.
Remove UILabel form view.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
for (UILabel *lbl in cell.contentView.subviews)
{
if ([lbl isKindOfClass:[UILabel class]])
{
[lbl removeFromSuperview];
}
}
UILabel *lblCategoryTitle =[[UILabel alloc]init];
[lblCategoryTitle setFont: [UIFont fontWithName:#"OpenSans-Bold" size:14]];
lblCategoryTitle.textAlignment = NSTextAlignmentCenter;
lblCategoryTitle.frame = CGRectMake(3.5, 90, 90, 24);
lblCategoryTitle.textColor = [UIColor blackColor];
lblCategoryTitle.text = #"Product 1";
lblCategoryTitle.backgroundColor = [UIColor clearColor];
lblCategoryTitle.numberOfLines = 2;
[cell.contentView addSubview:lblCategoryTitle];
return cell;
}
Use tag to get Label
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
UILabel *lblCategoryTitle =(UILabel *) [cell viewWithTag:5];
if (!lblCategoryTitle) {
lblCategoryTitle=[[UILabel alloc]init];
[cell.contentView addSubview:lblCategoryTitle];
}
[lblCategoryTitle setFont: [UIFont fontWithName:#"OpenSans-Bold" size:14]];
lblCategoryTitle.tag=5;
lblCategoryTitle.textAlignment = NSTextAlignmentCenter;
lblCategoryTitle.frame = CGRectMake(3.5, 90, 90, 24);
lblCategoryTitle.textColor = [UIColor blackColor];
lblCategoryTitle.text = #"Product 1";
lblCategoryTitle.backgroundColor = [UIColor clearColor];
lblCategoryTitle.numberOfLines = 2;
return cell;
}

Resources