具有动态单元格内容的UICollectionView - 让单元格记住状态

时间:2014-07-04 09:11:54

标签: ios uicollectionview

我有UICollectionView包含动态内容。我遇到的问题是,当单元格为dequeued时,它会忘记它的状态。在我的- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath中,我有一个布尔值,当它为真时,它会变为真实的图像,但是当它为假时,它会变为假图像。然而,当我向下滚动并向后滚动时,细胞会忘记那里的状态。有没有办法让细胞记住它的状态?这是我的内容

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath   

    SalesCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    SaleImage * saleImage = [self.SaleObjs objectAtIndex:indexPath.row];
    cell.bgImageView.image = [UIImage imageNamed:saleImage.imageName];
    if (saleImage.isBookable) {
        cell.isBookable = YES;
    }
    else{
        cell.isBookable=NO;
    }

return cell;
}

我有一个补救措施,但它会影响性能。我将它添加到我的自定义单元格中;

-(void)prepareForReuse{
    [super prepareForReuse];


    [self setNeedsLayout];
}

这是我的集合视图单元格;

@implementation SalesCollectionViewCell


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        // Initialization code
        self.layer.cornerRadius = 6.0;
        self.bgImageView = [[UIImageView alloc] init];
        self.book = [[UILabel alloc] init];      
        [self.contentView insertSubview:self.bgImageView atIndex:0];


         return self;
}

-(void)layoutSubviews{

    [super layoutSubviews];

    if (self.isBookable) {
        self.book.frame =CGRectMake(0, self.bounds.size.height - 41, 140, 41);
        self.book.text = @"Book this Item";
        self.book.textColor = [UIColor whiteColor];
        self.book.adjustsFontSizeToFitWidth=YES;
        self.book.textAlignment = NSTextAlignmentCenter;
        self.book.backgroundColor= [UIColor darkGrayColor];
        self.book.font = [UIFont fontWithName:kAppFont size:17.0];
        [self.contentView insertSubview:self.book atIndex:2];

        self.bgImageView.frame =CGRectMake(0, 0, 140, self.bounds.size.height - self.book.bounds.size.height);


    }
    else{
        self.bgImageView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);

    }



}

-(void)prepareForReuse{
    [super prepareForReuse];

    [self.book removeFromSuperview];
    [self setNeedsLayout];


}

6 个答案:

答案 0 :(得分:5)

细胞不应该记得"他们的国家;集合视图或表视图数据源应该。在相应的cellForIndexPath方法中,您应该设置单元格的当前状态,并让它根据需要进行自我配置。

答案 1 :(得分:2)

- (void)prepareForReuse {
  [super prepareForReuse];
  self.isBookable = nil;
  [self.book removeFromSuperview];
  [self setNeedsLayout];
}

尝试将isBookable设为零。我假设单元格使用前一个单元格的isBookable值设置其布局。

答案 2 :(得分:2)

正如@iphonic所说,isBookable属性应该(重新)从单元格中完全移出。 UICollectionView中的单元格大部分时间都在重用,因此即使您的saleImage.isBookable处于正确状态,您的cell.isBookable可能也不是。

我会做以下事情:

if(saleImage.isBookable){
  self.bgImageView.frame = CGRectMake(0, 0, 140, self.bounds.size.height - self.book.bounds.size.height);
  cell.bgImageView.image = [UIImage imageNamed:saleImage.imageName];
  cell.book.hidden = NO;
}
else{
 self.bgImageView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
 cell.bgImageView.image = nil;
 cell.book.hidden = YES;
}

[cell layoutIfNeeded];

collectionView: cellForItemAtIndexPath:内。

我也已经完成了在initWithFrame中设置书籍UILabel并最初隐藏它。类似的东西:

- (id)initWithFrame:(CGRect)frame{
    self.layer.cornerRadius = 6.0;
    self.bgImageView = [[UIImageView alloc] init];
    [self.contentView insertSubview:self.bgImageView atIndex:0];

    self.book = [[UILabel alloc] initWithFrame:CGRectMake(0, self.bounds.size.height - 41, 140, 41)];      

    self.book.text = @"Book this Item";
    self.book.textColor = [UIColor whiteColor];
    self.book.adjustsFontSizeToFitWidth=YES;
    self.book.textAlignment = NSTextAlignmentCenter;
    self.book.backgroundColor= [UIColor darkGrayColor];
    self.book.font = [UIFont fontWithName:kAppFont size:17.0];
    self.book.hidden = YES;

    [self.contentView insertSubview:self.book atIndex:2];
}

然后您不需要覆盖layoutSubviews

希望有所帮助。

答案 3 :(得分:1)

我在单元格类中重写isBookable setter:

- (void) setIsBookable:(BOOL)isBookable
{
    BOOL needsLayout = isBookable != _isBookable;
    _isBookable = isBookable;
    if(needsLayout)
    {
        [self.book removeFromSuperview];
        [self setNeedsLayout];
    }
}

另外,我建议您使用@property (nonatomic) BOOL isBookable;更改@property (nonatomic, getter = isBookable) BOOL bookable;以遵守Apple Code Convention。

答案 4 :(得分:1)

您需要创建两种具有不同标识符的单元格:

     static NSString *Bookable = @"Bookable";
     static NSString *NonBookable = @"NonBookable";
     NSString *currentIdentifier;
     if(saleImage.isBookable)//isBookable property must be set in SaleImage class
     {
          currentIdentifier = Bookable;
     }
     else{
          currentIdentifier = NonBookable;
     }


     SalesCollectionViewCell *cell = (SalesCollectionViewCell*)[collectionView dequeueReusableCellWithIdentifier:currentIdentifier];

答案 5 :(得分:0)

1st - 保存/保留更改的单元格的indexPath。

第二 -

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath   

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

    if (indexPath == self.changedIndexPath)
        [cell trueImage];
    else
        [cell falseImage];
return cell;
}

在单元格内部,您只需实现-(void) trueImage- (void) falseImage来更改单元格内的图像。

我希望我帮助过。)