刷新时,UICollectionView重复并重新排序单元格内容

时间:2014-05-16 22:40:34

标签: ios objective-c cocoa-touch uikit uicollectionview

我正在尝试使用iTunes U CS193P iOS编程课程。我使用UICollectionView来解决一些问题,以显示卡片作为Set游戏实施的一部分。点击导致UICollectionView刷新的卡片时,我发现了一种非常奇怪的行为。内容将被重新排序,有时在视图中重复。请参阅前后两个here的示例。

我相当肯定这与我的UICollectionView实现有关,因为游戏逻辑已经使用按钮进行了测试。

点击"查看控制器中的代码":

- (IBAction)touchCard:(UITapGestureRecognizer *)sender {
    CGPoint tapLocation = [sender locationInView:self.cardCollectionView];
    NSIndexPath *indexPath = [self.cardCollectionView indexPathForItemAtPoint:tapLocation];
    if (indexPath) {
        [self.game chooseCardatIndex:indexPath.item];
        [self updateUI];
    }
}

updateUI代码:

- (void)updateUI
{
    // Reload data for cardCollectionView
    [self.cardCollectionView reloadData];

    // For each cell within the UICollectionViewCell
    for (UICollectionViewCell *cell in [self.cardCollectionView visibleCells]) {

        NSIndexPath *indexPath = [self.cardCollectionView indexPathForCell:cell];
        Card *card = [self.game cardAtIndex:indexPath.item];
        if([card isKindOfClass:[SetCard class]]) {
            SetCard *setcard = (SetCard *)card;
            NSLog([NSString stringWithFormat:@"index %d updated with %d,%d,%d,%d",indexPath.item,setcard.rank,setcard.color,setcard.shape,setcard.pattern]);
            // Updates individual cards for each cardCollectionView
            [self updateCell:cell usingCard:card animated:YES];
        }
    }
}

这会更新单元格视图:

- (void)updateCell:(UICollectionViewCell *)cell usingCard:(Card *)card animated:(BOOL)animated
{
    setCardView *cardView = ((setCardCellView *)cell).setCardV;

    if([card isKindOfClass:[SetCard class]]) {
        SetCard *setCard = (SetCard *)card;

        // Set attributes of the card in the cardView
        cardView.rank = setCard.rank;
        cardView.shape = setCard.shape;
        cardView.pattern = setCard.pattern;
        cardView.color = setCard.color;

        // Set chosen cards
        cardView.selected = setCard.isChosen;
    }
}

最后需要collectionView方法cellForItemAtIndexPath

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[self reuseIdentifier] forIndexPath:indexPath];
    Card *card = [self.game cardAtIndex:indexPath.item];

    [self updateCell:cell usingCard:card animated:YES];
    return cell;
}

感谢您的协助。

1 个答案:

答案 0 :(得分:1)

实现cellForRowAtIndexPath / cellForItemAtIndexPath方法时,必须完全配置从dequeue方法返回的每个单元格。

如果该行的卡片对象属于SetCard类型,则您的代码仅配置单元格。如果卡对象不是SetCard,则单独保留该单元格。这意味着如果您从出列方法获得的单元格以前用于显示SetCard,但卡片对象不是SetCard,则单元格的视图不会被更改,并且仍将显示旧的值。

在if语句中添加一个else子句,如果卡对象不是SetCard类,则将字段设置回默认状态。