UICollectionView上的可重用性问题

我曾与UITableView工作,但我从来没有在我的应用程序中使用UICollectionView 。 所以我想以编程方式创buildUICollectionView

以下是我的代码:

 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]; 

委托和数据源方法。

 #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 } 

然后我的屏幕看起来像

在这里输入图像说明

问题1 –看上面的屏幕,你会看到第一和第三个项目看起来模糊(见产品1 ),然后第二/中间项目? 为什么这是发生?

每当我向上/向下滚动UICollectionView然后项目被覆盖,看看下一个图像

在这里输入图像说明

看了这个图像之后,从我的UITableView经验来看,这是因为UICollectionView的cell可重用性发生的。

问题2 –那我该如何解决呢?

请给我你的build议,并帮助我在这个问题上。

编辑:( build议@Dima

自定义单元格

.h文件

 #import <UIKit/UIKit.h> @interface customeGridCell : UICollectionViewCell @property (nonatomic, strong) UIImageView *imgPhoto; @property (nonatomic, strong) UILabel *lblCategoryTitle; @end 

.m文件

 #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; } 

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; } 

问题出在你的collectionView:cellForItemAtIndexPath:方法中。 每次重复使用单元格时,都要添加这些子视图。

您应该创build一个UICollectionViewCell子类,并将所有您需要的额外子视图添加到其初始化程序中。 这将确保他们只添加一次。

示例代码:

这里是你如何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; } 

那么当你抓住一个单元时,你只需要做一些事情:

 - (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; } 

你可以用两种方法做到这一点。

删除UILabel表单视图。

  - (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; } 

使用标签来获得标签

  - (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; }