0

尝试在 iOS 中重新加载 UICollectionview 时遇到问题。

我用它来显示游戏中的关卡。

集合视图由 10 个单元格组成。单元格的内容取决于关卡是否解锁。如果关卡解锁,单元格会显示关卡(自定义 UIView),否则会显示图像。我必须创建单独的单元格标识符才能使其正常工作,并且一切都在加载时完美显示。

我的问题是当用户正在玩解锁级别然后解锁下一个级别时。当用户从游戏视图导航回到关卡选择视图时,单元格没有正确重新加载(只是在自定义视图应该是空的地方显示,图像正确显示)。

我试图在 viewWillAppear 中卸载带有级别的数组,然后调用 [collectionview reloadData];,然后加载级别并再次重新加载 collectionview,但这无济于事。

如何在显示视图时清空整个 collectionview 并重新创建单元格标识符?

谢谢

-编辑!用代码更新 -

-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];

levelsArray = nil;
puzzlesArray = nil;

levelsArray = [[NSMutableArray alloc]init];
puzzlesArray = [[NSMutableArray alloc]init];

[collectionView reloadData];

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"puzzles"];
puzzlesArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];

if ([puzzlesArray count] == 0) {
    [self.navigationController popViewControllerAnimated:YES];
}
else {
    NSLog(@"%i puzzles loaded", [puzzlesArray count]);

    //Get alle puzzles for the current category
    for (Puzzle *puzzle in puzzlesArray) {

        if ([[[NSUserDefaults standardUserDefaults]objectForKey:@"Category"] isEqualToString:[puzzle categoryName]]) {
            [levelsArray addObject:puzzle];
        }

    }

}

NSLog(@"View will appear");
[collectionView reloadData];

}

并在索引路径的项目的单元格中

    - (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath; {

    BOOL isUnlocked = [self isPuzzleUnlocked:[indexPath row]];

    if ([[NSUserDefaults standardUserDefaults]boolForKey:@"u"] == YES) {
        isUnlocked = YES;
    }

    [self.collectionView registerNib:[UINib nibWithNibName:@"CVCell" bundle:nil] forCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d", kCellReuseIdentifier, indexPath.row]];

    CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d", kCellReuseIdentifier, indexPath.row] forIndexPath:indexPath];

[cell setPuzzleInfo:[levelsArray objectAtIndex:[indexPath row]] unlocked:isUnlocked];

        return cell;

}
4

2 回答 2

1

符合 Rob 的建议。

-(void)viewWillAppear {
   [super viewWillAppear];
   [self.collectionView reloadData]; 
}

cellForItemAtIndexPath您应该简单地检查项目是否已解锁并显示正确的图像或自定义单元格。

就这样。绝对没有必要重新创建集合视图。

您可能希望通过让您的游戏控制器和关卡控制器都可以访问为关卡建模的数据来尊重 MVC(模型-视图-控制器)设计模式。当游戏中发生的事情解锁新关卡时,它应该更改此数据。集合视图应该在它出现之前根据这些数据重新加载。

编辑:

如果您得到与以前相同的单元格/项目,即使您reloadData,这意味着您的配置设置不正确。关键是显设置这两种状态-如果项目发生变化,则将更新项目。unlocked reloadData

编辑2:

你这两种itemForRowAtIndexPath方法都搞砸了。呼叫registerNib根本不属于那里!它应该在初始化过程中被调用。如果您使用情节提要,则根本没有必要。

这是一个您应该使用的简单框架:

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv 
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath; {

   PuzzleInfo *puzzleObject = [dataArray objectAtIndex:indexPath.row]; 
   // you can use your more complicated data structure here, but 
   // have one object, dictionary, array item, etc. that has the info you need

   NSString *identifier = puzzleObject.unlocked ? kUnlockedCell : kLockedCell;
   CVCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier
           forIndexPath:indexPath];

   if (puzzleObject.unlocked) {
      // configure the unlocked cell 
   }
   else {
      // configure the locked cell
   }

   return cell;
}
于 2013-06-20T16:23:33.557 回答
-3

我修好了它!

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath; {
NSLog(@"CALLED");
BOOL isUnlocked = [self isPuzzleUnlocked:[indexPath row]];

if ([[NSUserDefaults standardUserDefaults]boolForKey:@"u"] == YES) {
    isUnlocked = YES;
}
int rand = arc4random() % 99001;
[self.collectionView registerNib:[UINib nibWithNibName:@"CVCell" bundle:nil] forCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d%i", kCellReuseIdentifier, indexPath.row, rand]];

CVCell *cell = (CVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:[NSString stringWithFormat:@"%@%d%i", kCellReuseIdentifier, indexPath.row, rand] forIndexPath:indexPath];
[cell setPuzzleInfo:[levelsArray objectAtIndex:[indexPath row]] unlocked:isUnlocked];

    return cell;

}

不是一个非常有效的内存解决方案(或优雅的),但它有效。向每个单元格添加一个随机数会强制每次重新创建它。只要我在collectionview中只有10个单元格,我认为就可以了..

感谢你的帮助 :]

于 2013-06-21T06:22:58.753 回答