UICollectionViewCell 问题与 registerClass
UICollectionViewCell issues with registerClass
我正在尝试在不使用故事板或 nib 的情况下以编程方式创建集合视图单元格。
这是我的cell.h文件
#import <UIKit/UIKit.h>
@interface TestCVCell : UICollectionViewCell {
UILabel *label;
}
@property (nonatomic, retain) UILabel *label;
@end
这是 .m 文件
#import "TestCVCell.h"
@implementation TestCVCell
@synthesize label;
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
if (!self.label) {
label = [[UILabel alloc] initWithFrame:self.frame];
label.textColor = [UIColor whiteColor];
self.contentView.backgroundColor = [UIColor orangeColor];
[self.contentView addSubview:label];
}
}
return self;
}
- (void)prepareForReuse
{
self.label.text = @"";
}
@end
我遇到的问题是,当我注册 class 时,它偶尔会显示单元格,并且没有在正确的位置显示它们。滚动时单元格也会随机 disappear/appear(通常不在同一位置)。
奇怪的是,如果我创建一个笔尖并注册笔尖而不是class,一切都很好。
我能想到的笔尖和 class 之间的唯一区别是笔尖,我使用 -(id)initWithCoder:(NSCoder *)aDecoder
而不是 -(instancetype)initWithFrame:(CGRect)frame
。
这里是集合视图文件供参考
.h
#import <UIKit/UIKit.h>
@interface TestCollectionView : UICollectionView
@end
.m
#import "TestCollectionView.h"
#import "TestCVCell.h"
@interface TestCollectionView () <UICollectionViewDataSource>
@property (nonatomic, strong) NSMutableArray *itemArray;
@end
@implementation TestCollectionView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame collectionViewLayout:[self collectionViewLayout]];
if (self) {
[self registerClass:[TestCVCell class] forCellWithReuseIdentifier:@"cell"];
self.itemArray = [[NSMutableArray alloc] init];
self.dataSource = self;
for (int idx = 0; idx < 50; idx++) {
[self.itemArray addObject:[NSNumber numberWithInt:idx]];
}
}
return self;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.itemArray.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
TestCVCell *cell = (TestCVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
cell.label.text = [NSString stringWithFormat:@"%@", [self.itemArray objectAtIndex:indexPath.item]];
return cell;
}
- (UICollectionViewLayout *)collectionViewLayout
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(50, 50);
return layout;
}
@end
有没有人遇到过这个问题或类似的问题?
在此先感谢您的帮助。
这是你的问题,你的 TestCVCell Class 正在初始化期间初始化标签,然后 collectionView 正在重用相同的单元格,请记住在重用期间我们不初始化新对象,我们只是回收现有的一,因此您的标签永远不会在后续重复使用时设置。对您的 TestCVCell class.
进行以下更改
TestCVCell.h
@interface TestCVCell : UICollectionViewCell
@property (nonatomic) UILabel *label;
@end
您不再需要 iVar 标签。如果需要,我们将使用自动合成的 _label iVar。
使用延迟加载来初始化标签,它不仅聪明而且更干净,自定义 getter 如下所示,还记得在 prepareForReuse
#import "TestCVCell.h"
@implementation TestCVCell
- (UILabel *)label {
if (!_label) {
_label = [[UILabel alloc] initWithFrame:self.bounds];
_label.textColor = [UIColor whiteColor];
_label.textAlignment = NSTextAlignmentCenter;
self.contentView.backgroundColor = [UIColor orangeColor];
[self.contentView addSubview:_label];
}
return _label;
}
- (void)prepareForReuse
{
[super prepareForReuse];
self.label.text = @"";
}
@end
上面的代码只是在contentView没有初始化的情况下才给contentView添加label,只有在需要的时候才会初始化一个新的label,实现懒加载。删除整个 init 方法,不需要。以上是您对 TestCVCell 的整个实现。简洁易懂。
我正在尝试在不使用故事板或 nib 的情况下以编程方式创建集合视图单元格。
这是我的cell.h文件
#import <UIKit/UIKit.h>
@interface TestCVCell : UICollectionViewCell {
UILabel *label;
}
@property (nonatomic, retain) UILabel *label;
@end
这是 .m 文件
#import "TestCVCell.h"
@implementation TestCVCell
@synthesize label;
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
if (!self.label) {
label = [[UILabel alloc] initWithFrame:self.frame];
label.textColor = [UIColor whiteColor];
self.contentView.backgroundColor = [UIColor orangeColor];
[self.contentView addSubview:label];
}
}
return self;
}
- (void)prepareForReuse
{
self.label.text = @"";
}
@end
我遇到的问题是,当我注册 class 时,它偶尔会显示单元格,并且没有在正确的位置显示它们。滚动时单元格也会随机 disappear/appear(通常不在同一位置)。
奇怪的是,如果我创建一个笔尖并注册笔尖而不是class,一切都很好。
我能想到的笔尖和 class 之间的唯一区别是笔尖,我使用 -(id)initWithCoder:(NSCoder *)aDecoder
而不是 -(instancetype)initWithFrame:(CGRect)frame
。
这里是集合视图文件供参考
.h
#import <UIKit/UIKit.h>
@interface TestCollectionView : UICollectionView
@end
.m
#import "TestCollectionView.h"
#import "TestCVCell.h"
@interface TestCollectionView () <UICollectionViewDataSource>
@property (nonatomic, strong) NSMutableArray *itemArray;
@end
@implementation TestCollectionView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame collectionViewLayout:[self collectionViewLayout]];
if (self) {
[self registerClass:[TestCVCell class] forCellWithReuseIdentifier:@"cell"];
self.itemArray = [[NSMutableArray alloc] init];
self.dataSource = self;
for (int idx = 0; idx < 50; idx++) {
[self.itemArray addObject:[NSNumber numberWithInt:idx]];
}
}
return self;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.itemArray.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
TestCVCell *cell = (TestCVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
cell.label.text = [NSString stringWithFormat:@"%@", [self.itemArray objectAtIndex:indexPath.item]];
return cell;
}
- (UICollectionViewLayout *)collectionViewLayout
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(50, 50);
return layout;
}
@end
有没有人遇到过这个问题或类似的问题?
在此先感谢您的帮助。
这是你的问题,你的 TestCVCell Class 正在初始化期间初始化标签,然后 collectionView 正在重用相同的单元格,请记住在重用期间我们不初始化新对象,我们只是回收现有的一,因此您的标签永远不会在后续重复使用时设置。对您的 TestCVCell class.
进行以下更改TestCVCell.h
@interface TestCVCell : UICollectionViewCell
@property (nonatomic) UILabel *label;
@end
您不再需要 iVar 标签。如果需要,我们将使用自动合成的 _label iVar。
使用延迟加载来初始化标签,它不仅聪明而且更干净,自定义 getter 如下所示,还记得在 prepareForReuse
#import "TestCVCell.h"
@implementation TestCVCell
- (UILabel *)label {
if (!_label) {
_label = [[UILabel alloc] initWithFrame:self.bounds];
_label.textColor = [UIColor whiteColor];
_label.textAlignment = NSTextAlignmentCenter;
self.contentView.backgroundColor = [UIColor orangeColor];
[self.contentView addSubview:_label];
}
return _label;
}
- (void)prepareForReuse
{
[super prepareForReuse];
self.label.text = @"";
}
@end
上面的代码只是在contentView没有初始化的情况下才给contentView添加label,只有在需要的时候才会初始化一个新的label,实现懒加载。删除整个 init 方法,不需要。以上是您对 TestCVCell 的整个实现。简洁易懂。