UICollectionView con contenido dynamic de celda: get celda para recordar estado

Tengo una UICollectionView que contiene contenido dynamic. El problema que estoy teniendo es que cuando se dequeued la celda olvida su estado. En mi - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath Tengo un valor boolean que cuando es verdadero, cambia a una image verdadera, pero cuando es falso, cambia a una falsa image. Sin embargo, cuando me desploop hacia abajo y hacia atrás, las celdas olvidan su estado. ¿Hay alguna forma de hacer que una célula recuerde su estado? Aquí está lo que está dentro de mi

 - (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; } 

Tengo un remedio para esto pero afecta el performance. Agrego esto a mi celda personalizada;

 -(void)prepareForReuse{ [super prepareForReuse]; [self setNeedsLayout]; } 

Aquí está mi celda de vista de colección;

 @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]; } 

Como dijo @iphonic, la propiedad isBookable debe (re) moverse desde la celda por completo. Las celdas en un UICollectionView se están reutilizando la mayoría del time, por lo que aunque your saleImage.isBookable esté en el estado correcto de su cell.isBookable probablemente no.

Yo haría lo siguiente:

 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]; 

inside collectionView: cellForItemAtIndexPath:

También habría terminado de configurar el libro UILabel dentro de initWithFrame y tenerlo inicialmente oculto. Algo como:

 - (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]; } 

Entonces no necesitarías replace layoutSubviews .

Espero que ayude.

Las células no deben "recordar" su estado; Vista de colección o fuente de datos de la vista de tabla. En el método cellForIndexPath respectivo, debe establecer el estado actual de la celda y dejar que se configure como sea necesario.

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

Intente configurar isBookable to nil. Estoy asumiendo que la celda está configurando su layout con el valor de la celda anterior isBookable .

isBookable en la class de celda:

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

También recomiendo cambiar @property (nonatomic) BOOL isBookable; con @property (nonatomic, getter = isBookable) BOOL bookable; para seguir la Convención del Código de Apple.

Necesita crear dos types de celdas con diferentes identificadores:

  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]; 

1st – Guardar / mantener indexPath de la celda que se cambia.

Segundo

 - (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; } 

Dentro de la celda, simplemente implementa el -(void) trueImage y el - (void) falseImage que cambia la image dentro de la celda.

Espero haber ayudado 🙂