UICollectionViewCell 的自定义实现使单元格不可见
Custom implementation of UICollectionViewCell makes cells invisible
为了上下文,我正在开发一个具有 3 个不同视图的日历应用程序。日、月和年视图。
为了显示天数,我决定使用 UICollectionView
和 UICollectionViewCell
的自定义实现(以便我能够自定义每个单元格的外观)。
在我的 NSObject
CtrlCalendar class 的 init
上,我像这样注册 3 个单元格 类:
//Used for the yearView
[self.grid registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"monthCell"];
//Used for the monthView
[self.grid registerClass:[CollectionViewCell class] forC ellWithReuseIdentifier:@"dayCell"];
//Used for the dayView
[self.grid registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"hourCell"];
然后,在 collectionView:collectionView cellForItemAtIndexPath:indexPath
我正在做如下事情:
CollectionViewCell *cell = nil;
if ([self.currentDisplayType isEqualToString:@"monthView"]) {
cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"dayCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor grayColor];
self.month = [self.displayingViews get:indexPath.section];
if (indexPath.row + 1 >= self.month.firstWeekDay && indexPath.row + 1 < self.month.numberOfDays + (self.month.firstWeekDay)) {
NSDateComponents *tempDay = [self.calendar components:NSCalendarUnitDay fromDate:self.month.date];
cell.date = [self.dateHelper addToDate:self.month.date days:(int)(tempDay.day + indexPath.row - self.month.firstWeekDay)];
cell.cellTitle.text = [NSString stringWithFormat:@"%i", (int)(tempDay.day + indexPath.row + 1 - self.month.firstWeekDay)];
cell.cellTitle.textColor = [UIColor blackColor];
if ([[self.dateHelper addToDate:self.month.date days:(indexPath.row + 1 - self.month.firstWeekDay)] isEqualToDate:self.today]) {
cell.cellTitle.textColor = [UIColor redColor];
}
cell.userInteractionEnabled = YES;
cell.separator.hidden = NO;
cell.contentView.hidden = NO;
} else {
cell.userInteractionEnabled = NO;
}
最后是我对 CollectionViewCell
:
的实现
@interface CollectionViewCell ()
@property (nonatomic, retain) UILabel *cellTitle;
@property (nonatomic, retain) NSString *titleText;
@property (nonatomic, retain) UILabel *separator;
@property (nonatomic, retain) NSDate *date;
@end
@implementation CollectionViewCell
@synthesize cellTitle;
@synthesize titleText;
@synthesize separator;
@synthesize date;
- (void)dealloc {
[cellTitle release];
[titleText release];
[separator release];
[date release];
[super dealloc];
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.cellTitle = [[[UILabel alloc] initWithFrame:self.bounds] autorelease];
self.cellTitle.textColor = [UIColor blackColor];
self.cellTitle.textAlignment = NSTextAlignmentCenter;
self.separator = [[[UILabel alloc] initWithFrame:CGRectMake(0, (self.frame.size.height - 0.25), self.frame.size.width, 0.5)] autorelease];
self.separator.backgroundColor = [UIColor lightGrayColor];
[self.contentView addSubview:self.separator];
[self.contentView addSubview:self.cellTitle];
}
return self;
}
- (void)prepareForReuse {
[super prepareForReuse];
self.cellTitle.text = nil;
self.separator.hidden = YES;
[self.cellTitle setTextColor:[UIColor blackColor]];
//the presence of this line is explained after the edit bellow
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}
@end
我第一次 运行 应用程序时,月视图按预期配置,但一旦它执行出队,单元格就会变成空白。
经过一些调试我发现 CollectionViewCell
的 cellTitle
属性 设置正确。问题在于出队后标签由于某种原因被隐藏了。
我知道这是一个很长的问题,但是如果您无论如何都可以提供帮助或认识可以提供帮助的人,请告诉我!
非常感谢!
为了澄清问题所在,我添加了一些屏幕
滚动前:
滚动后:
更新 1
正如@Alessandro Chiarotto 回答的那样,
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]
确实使单元格变空。这里需要注意的是,我需要该选择器从单元格中删除一些我添加到 yearView
.
的 UILabel
我的 yearView
UICollection 有 12 个单元格(每个月一个)。每个单元格都有 UILabels 的数量作为每个月的天数。我从 collectionView:collectionView cellForItemAtIndexPath:indexPath
添加这个 UILabels,如下所示:
for (int d = 1; d < self.month.numberOfDays; d++) {
UILabel *day = [[[UILabel alloc] initWithFrame:dayRect] autorelease];
day.text = currentDay;
[cell addSubview:day];
}
如果我不在 prepareForReuse
中执行选择器,在滚动视图后,每个月单元格中的所有 day
标签都是重复的。
如果您滚动集合,则 prepareForReuse
将被调用。在 prepareForReuse
中,您有以下调用:
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
这将删除单元格的所有子视图(UILabel 等)。
此时您的手机将"white"...
我找到问题了。正如@Alessandro 在他的回答中所说,[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
正在从单元格中删除所有内容,因此使其空白。
如果不是另一个方面的问题就这样了。
正如我在更新问题中所说,我需要该选择器来删除 yearView
中添加的一些 UILabel。这些标签是每个月单元格中的日期。
解法:
我在 CollectionViewCell
中添加了一个 UIView
属性,它的边框等于单元格的边界。然后我将 UILabel 添加到此视图,然后在 prepareForReuse
上我在 self.labelsView.subviews
上执行 removeFromSuperView
。它就像一个魅力。
prepareForReuse
的正确实现应该是:
- (void)prepareForReuse {
[super prepareForReuse];
self.cellTitle.text = nil;
self.separator.hidden = YES;
[self.cellTitle setTextColor:[UIColor blackColor]];
[self.labelsView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}
为了上下文,我正在开发一个具有 3 个不同视图的日历应用程序。日、月和年视图。
为了显示天数,我决定使用 UICollectionView
和 UICollectionViewCell
的自定义实现(以便我能够自定义每个单元格的外观)。
在我的 NSObject
CtrlCalendar class 的 init
上,我像这样注册 3 个单元格 类:
//Used for the yearView
[self.grid registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"monthCell"];
//Used for the monthView
[self.grid registerClass:[CollectionViewCell class] forC ellWithReuseIdentifier:@"dayCell"];
//Used for the dayView
[self.grid registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"hourCell"];
然后,在 collectionView:collectionView cellForItemAtIndexPath:indexPath
我正在做如下事情:
CollectionViewCell *cell = nil;
if ([self.currentDisplayType isEqualToString:@"monthView"]) {
cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"dayCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor grayColor];
self.month = [self.displayingViews get:indexPath.section];
if (indexPath.row + 1 >= self.month.firstWeekDay && indexPath.row + 1 < self.month.numberOfDays + (self.month.firstWeekDay)) {
NSDateComponents *tempDay = [self.calendar components:NSCalendarUnitDay fromDate:self.month.date];
cell.date = [self.dateHelper addToDate:self.month.date days:(int)(tempDay.day + indexPath.row - self.month.firstWeekDay)];
cell.cellTitle.text = [NSString stringWithFormat:@"%i", (int)(tempDay.day + indexPath.row + 1 - self.month.firstWeekDay)];
cell.cellTitle.textColor = [UIColor blackColor];
if ([[self.dateHelper addToDate:self.month.date days:(indexPath.row + 1 - self.month.firstWeekDay)] isEqualToDate:self.today]) {
cell.cellTitle.textColor = [UIColor redColor];
}
cell.userInteractionEnabled = YES;
cell.separator.hidden = NO;
cell.contentView.hidden = NO;
} else {
cell.userInteractionEnabled = NO;
}
最后是我对 CollectionViewCell
:
@interface CollectionViewCell ()
@property (nonatomic, retain) UILabel *cellTitle;
@property (nonatomic, retain) NSString *titleText;
@property (nonatomic, retain) UILabel *separator;
@property (nonatomic, retain) NSDate *date;
@end
@implementation CollectionViewCell
@synthesize cellTitle;
@synthesize titleText;
@synthesize separator;
@synthesize date;
- (void)dealloc {
[cellTitle release];
[titleText release];
[separator release];
[date release];
[super dealloc];
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.cellTitle = [[[UILabel alloc] initWithFrame:self.bounds] autorelease];
self.cellTitle.textColor = [UIColor blackColor];
self.cellTitle.textAlignment = NSTextAlignmentCenter;
self.separator = [[[UILabel alloc] initWithFrame:CGRectMake(0, (self.frame.size.height - 0.25), self.frame.size.width, 0.5)] autorelease];
self.separator.backgroundColor = [UIColor lightGrayColor];
[self.contentView addSubview:self.separator];
[self.contentView addSubview:self.cellTitle];
}
return self;
}
- (void)prepareForReuse {
[super prepareForReuse];
self.cellTitle.text = nil;
self.separator.hidden = YES;
[self.cellTitle setTextColor:[UIColor blackColor]];
//the presence of this line is explained after the edit bellow
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}
@end
我第一次 运行 应用程序时,月视图按预期配置,但一旦它执行出队,单元格就会变成空白。
经过一些调试我发现 CollectionViewCell
的 cellTitle
属性 设置正确。问题在于出队后标签由于某种原因被隐藏了。
我知道这是一个很长的问题,但是如果您无论如何都可以提供帮助或认识可以提供帮助的人,请告诉我!
非常感谢!
为了澄清问题所在,我添加了一些屏幕
滚动前:
滚动后:
更新 1
正如@Alessandro Chiarotto 回答的那样,
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]
确实使单元格变空。这里需要注意的是,我需要该选择器从单元格中删除一些我添加到 yearView
.
我的 yearView
UICollection 有 12 个单元格(每个月一个)。每个单元格都有 UILabels 的数量作为每个月的天数。我从 collectionView:collectionView cellForItemAtIndexPath:indexPath
添加这个 UILabels,如下所示:
for (int d = 1; d < self.month.numberOfDays; d++) {
UILabel *day = [[[UILabel alloc] initWithFrame:dayRect] autorelease];
day.text = currentDay;
[cell addSubview:day];
}
如果我不在 prepareForReuse
中执行选择器,在滚动视图后,每个月单元格中的所有 day
标签都是重复的。
如果您滚动集合,则 prepareForReuse
将被调用。在 prepareForReuse
中,您有以下调用:
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
这将删除单元格的所有子视图(UILabel 等)。
此时您的手机将"white"...
我找到问题了。正如@Alessandro 在他的回答中所说,[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
正在从单元格中删除所有内容,因此使其空白。
如果不是另一个方面的问题就这样了。
正如我在更新问题中所说,我需要该选择器来删除 yearView
中添加的一些 UILabel。这些标签是每个月单元格中的日期。
解法:
我在 CollectionViewCell
中添加了一个 UIView
属性,它的边框等于单元格的边界。然后我将 UILabel 添加到此视图,然后在 prepareForReuse
上我在 self.labelsView.subviews
上执行 removeFromSuperView
。它就像一个魅力。
prepareForReuse
的正确实现应该是:
- (void)prepareForReuse {
[super prepareForReuse];
self.cellTitle.text = nil;
self.separator.hidden = YES;
[self.cellTitle setTextColor:[UIColor blackColor]];
[self.labelsView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}