UICollectionViewCell 的自定义实现使单元格不可见

Custom implementation of UICollectionViewCell makes cells invisible

为了上下文,我正在开发一个具有 3 个不同视图的日历应用程序。日、月和年视图。

为了显示天数,我决定使用 UICollectionViewUICollectionViewCell 的自定义实现(以便我能够自定义每个单元格的外观)。

在我的 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

我第一次 运行 应用程序时,月视图按预期配置,但一旦它执行出队,单元格就会变成空白。

经过一些调试我发现 CollectionViewCellcellTitle 属性 设置正确。问题在于出队后标签由于某种原因被隐藏了。

我知道这是一个很长的问题,但是如果您无论如何都可以提供帮助或认识可以提供帮助的人,请告诉我!

非常感谢!

为了澄清问题所在,我添加了一些屏幕

滚动前:

滚动后:

更新 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)];
}