UICollectionView 在刷新时重复和重新排序单元格内容
Posted
技术标签:
【中文标题】UICollectionView 在刷新时重复和重新排序单元格内容【英文标题】:UICollectionView Repeats and Reorders Cell Content When Refreshed 【发布时间】:2014-05-16 22:40:34 【问题描述】:我正在尝试完成 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】:当您实现 cellForRowAtIndexPath / cellForItemAtIndexPath 方法时,您必须完全配置从 dequeue 方法返回的每个单元格。
只有当该行的卡片对象是 SetCard 类型时,您的代码才会配置单元格。如果卡片对象不是 SetCard,则不理会该单元格。这意味着,如果您从 dequeue 方法获得的单元格以前用于显示 SetCard,但卡片对象不是 SetCard,则单元格的视图不会更改,并且仍会显示旧值。
如果卡片对象不属于 SetCard 类,则在 if 语句中添加一个 else 子句,将字段设置回默认状态。
【讨论】:
我添加了一个 else 子句,如果不是 SetCard 类则输出到日志。不幸的是,在测试中,else 子句永远不会执行,仍然会看到重新排序和复制单元格的相同行为。以上是关于UICollectionView 在刷新时重复和重新排序单元格内容的主要内容,如果未能解决你的问题,请参考以下文章
iOS UICollectionView 推送刷新时的意外行为
应用 NSDiffableDataSourceSnapshot 时,ViewController 中的 UICollectionView 拉取刷新跳转
禁用 UICollectionView 顶部的“拉动刷新”空间