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