'cellForItemAtIndexPath' 中的自定义单元格初始化导致堆叠单元格堆叠视图

Custom Cell init in 'cellForItemAtIndexPath' causing stacked cell to stack views

我使用这个函数创建了一个单元格:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    BOOL isFocusOn = [_userDefault boolForKey:@"mixFocusOn"];

    CDCChannelStrip *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];

    if (isFocusOn == TRUE) {
        NSNumber *setChan = [self.focusChannels objectAtIndex:indexPath.section];
        NSInteger chanInt = [setChan intValue];
        [cell initData:(chanInt)];
        [self getParameters:(setChan)];

    } else {
        NSInteger chanInt = indexPath.section;
        NSNumber *chanNum = [NSNumber numberWithInt:chanInt]; // doesnt matter
        [cell initData:(chanInt)]; // init
        [self getParameters:(chanNum)]; // params
    }

    [self.mixMonitorView setChannelsStripToType:(cell)];
    cell.clipsToBounds = YES;
    return cell;
}

有问题的函数是 initData,它看起来像这样:

- (void)initData:(NSInteger)channel {
        self.isBus = false;
        self.isSendChan = false;
        self.recallSafeFade = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"recallSafe"]];
        self.recallSafeFade.y = 80;
        [self.recallSafeFade setUserInteractionEnabled:YES];
        self.recallSafeHead = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"recallSafeHeadamp"]];
        [self.recallSafeHead setUserInteractionEnabled:NO];
        self.recallSafePan = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"recallSafePan"]];
        self.recallSafePan.y = 768 - 141;
        [self.recallSafePan setUserInteractionEnabled:YES];
        self.channelNumber = channel;
        [self setClipsToBounds:NO];
        _background = [[UIView alloc] initWithFrame:CGRectMake(0, 80, 122, 547)];
        [_background setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"singleFader"]]];
        [self addSubview:_background];
        [self addChannelName];
        [self addInput];
        [self addPan];
        [self addOn];
        [self addMeter];
        [self addFader];
}

所以我遇到的问题是,我需要调用此函数来设置我的自定义单元格,以按照我需要的方式查看和运行。但是,每次由于状态更改我在 collectionview 上调用重新加载时,它会将新视图分层放置在旧视图的顶部(由于重复出现 imageview alloc)

那么我如何才能自动将此功能应用于每个单元格,而不是在每次重新加载单元格时都在顶部重新应用它?

此处是视图调试器中的问题图片:

最简单的方法是为单元格或原型单元格创建一个单独的 xib。在那里设计你的单元格,在 cellForItemAtIndexPath 中你只需操纵你的视图并为你的标签、图像和其他控制器设置值。

UICollectionViewCell 被重用。因此,避免在 collectionView:cellForItemAtIndexPath: 中每次都执行 addSubView:(直接或间接,如您的情况:collectionView:cellForRowAtIndexPath: 正在调用 initData:,而 addSubView: 正在调用 addSubView:]。 =27=]

您仅通过代码使用 UICollectionViewUICollectionViewCell。 所以没有 XIB/Storyboard 是单元格,也没有 IBOutlet.
根据 dequeueReusableCellWithReuseIdentifier:forIndexPath: 的文档,这就是你属于的部分:

If you registered a class for the specified identifier and a new cell must be created, this method initializes the cell by calling its initWithFrame: method.

因此,在 CDCChannelStrip.m 中,覆盖 initWithFrame: 并初始化其属性(即 "always" visible/used)。

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        _myImageViewProperty = [[UIImageView alloc] initWithFrame:someFrame];
        [self addSubview:_myImageViewProperty];
        etc.
    }
    return self;
}

-(void)updateWithChannel:(NSInteger)channel
{
    self.channelNumber = channel;
    self.channelLabelName = @"Something";
    //etc.
}

您也可以使用 prepareForReuse 到 "reinit" 单元格作为 "virgin"(例如它就在 initWithFrame: 之后。

-(void)prepareForReuse
{
    [super prepareForReuse];
    self.channelLabelName = @"";
    self.backgroundColor = [UIColor clearColor]; 
    //etc.
    [self.sometimesThatImageIsShown setHidden:YES];

}