Rob d'Apice
Rob d'Apice

Reputation: 2416

How do I force a refresh of reused collectionview cells?

THE PROBLEM

I using multiple UICollectionViews that each occupy a cell in a UITableView, as per the image below:

enter image description here

Each Table View Cell contains a CollectionView that creates cells via dequeueReusableCellWithReuseIdentifier with the same nib identifier of PlayerCell.

The problem is that when the user scrolls down, the incoming Collection View cells calls collectionView:cellForItemAtIndexPath to populate the cells. It reuses the cells from the topmost Collection View that has disappeared, and given that the indexpath for the leftmost face in each Collection View is the same ('0'), it does not refresh the face in the Collection View cell.

How can I force the cell is refresh the face, and where should I make this call?

CODE EXTRACTS:

#ScoreCheckViewController.m
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return [scores count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    RankingCell *cell = [tableView dequeueReusableCellWithIdentifier:@"rankingCell"];
    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"RankingCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    [cell updateCellWithPlayers:[self getPlayersInfo:[[[scores objectAtIndex:indexPath.section] allValues] firstObject]]score:[[[scores objectAtIndex:indexPath.section] allKeys] firstObject] place:indexPath.section+1];
    return cell;
}

#RankingCell.m
-(void)updateCellWithPlayers:(NSArray *)players score:(NSString *)score place:(NSInteger)place{
    self.players = players;
    self.score = score;
    scoreLabel.text = [NSString stringWithFormat:@"%@ pts.",score];
    placeLabel.text = [self placeFormat:place];
    placeLabel.textColor = [self placeColor:place];
    bracketImageView.image = [self placeImage:place];

    rankingCollectionView.frame = CGRectMake(rankingCollectionView.frame.origin.x, rankingCollectionView.frame.origin.y, rankingCollectionView.frame.size.width, [self rowHeightForArray:self.players]);
    bracketImageView.frame = CGRectMake(bracketImageView.frame.origin.x, bracketImageView.frame.origin.y, bracketImageView.frame.size.width, rankingCollectionView.frame.size.height);
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, rankingCollectionView.frame.origin.y + rankingCollectionView.frame.size.height+10);
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    [rankingCollectionView registerNib:[UINib nibWithNibName:@"PlayerCell" bundle:nil] forCellWithReuseIdentifier:@"PlayerCell"];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    PlayerCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PlayerCell" forIndexPath:indexPath];
    UserObject *userObj = [self.players objectAtIndex:indexPath.section];
    [cell updateCellWithPlayerImage:userObj.image name:userObj.shortName];

    return cell;
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    return [self.players count];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return 1;
}

Upvotes: 1

Views: 4240

Answers (1)

AlexZd
AlexZd

Reputation: 2152

The problem is not UICollectionView takes cells from previous cell. The problem is that UITableView takes UITableViewCell which goes out from the screen for reuse and it contains all your UICollectionViewCells.

Try to add reloadData for your UICollectionView inside updateCellWithPlayers:

Upvotes: 4

Related Questions