UICollectionView 上的可重用性问题 [英] Reusability issue on UICollectionView
问题描述
我曾使用过 UITableView
,但我从未在我的应用程序中使用过 UICollectionView
.所以我想以编程方式创建 UICollectionView
.
I had worked with UITableView
but I have never ever use of UICollectionView
in my apps. So I want to create UICollectionView
programmatically.
以下是我的代码:
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 和第 3 项看起来很模糊(请参阅 产品 1) 然后是第 2 项/中间项目?为什么会这样?
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 ?
每当我向上/向下滚动 UICollectionView
时,项目都会被覆盖,查看下一张图片
And whenever I scroll up/down UICollectionView
then items are overwrite, Look at Next image
看了这张图片后,根据我对 UITableView
的经验,它的发生是因为 UICollectionView
的单元格的可重用性.
After looked this image, from my experience of UITableView
, it's happening because of Reusability of cell of UICollectionView
.
问题 2 - 那我该如何解决呢?
请给我你的建议并帮助我解决这个问题.
Please give my your suggestion and help me on this issue.
已 (@Dima 的建议)
EDITED: (suggestion of @Dima)
自定义单元格
#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:
方法中.每次重用单元格时,您都在添加这些子视图,彼此叠加.
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.
您应该创建一个 UICollectionViewCell
子类并将所有您想要的额外子视图添加到它的初始化程序中.这将确保它们只被添加一次.
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.
示例代码:
这是一个示例,说明如何将 UICollectionViewCell
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;
}
这篇关于UICollectionView 上的可重用性问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!