Please note, this blog entry is from a previous course. You might want to check out the current one.
In the Set game (only), the user must always have the option somewhere in the UI of requesting 3 more cards to be dealt at any time if he or she is unable to locate a Set.
In storyboard drag out a new button set its tag to 3, provide a suitable name and link it to an action in the game view controller (or the set-game view controller – either works).
In its action method draw the number of cards (according to the tag of the button = 3) and reload the data of the collection view:
- (IBAction)addCardsButtonPressed:(UIButton *)sender { for (int i = 0; i < sender.tag; i++) { [self.game drawNewCard]; } [self.cardCollectionView reloadData]; }
To be able to do so, the card-matching-game model needs a new public method:
- (void)drawNewCard;
… which just draws a new random card from the current deck:
- (void)drawNewCard { Card *card = [self.deck drawRandomCard]; if (card) { [self.cards addObject:card]; } }
Currently the deck is only available in the init method and must be stored in a new private property (note that needs to be strong because the calling method does not it need it later on):
@property (strong, nonatomic) Deck *deck;
… which is set in the init method:
- (id)initWithCardCount:(NSUInteger)count usingDeck:(Deck *)deck { ... _deck = deck; ... }
The complete code is available on github.
Just a question – why do you need to use reload data here? Is it possible to use reloadItemsAtIndexPath? Why wouldn’t you alternatively use insertItemsAtIndexPath?
… didn’t try that. I suppose you can add the cards separately, but take care that your model and your view are in sync! Please try and let us know!
I’m definitely having some problems getting my model and my collectionView to sync up correctly. Even with the methods you used, and especially when I try the insertItemsAtIndexPath method, I keep getting this sort of error:
Matchismo[13875:c07] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]’
I’m just a bit confused. I’ve noted in the lectures he says that reloadData is heavy handed and not necessary unless your whole model changes. I’ve tried many different combinations of methods but all seem to result in a crash.
Any idea why this error might be coming up?
Hey just thought I’d let you know I identified the issue. I hadn’t implemented the remove unplayable cards after a match was found which was an issue if all the cards being removed weren’t in the visible cells set.
So in terms of dealing new cards, this line:
[self.cardCollectionView insertItemsAtIndexPaths:@[indexPath]];
works instead of [self.cardCollectionView reloadData];
obviously you need the index path of the card to make the former work.
Cheers
When not using the brute force method of reloadData: you need to be especially careful that your model and your view are in sync! e.g. by performing batch updates https://cs193p.m2m.at/cs193p-assignment-3-extra-task-3/
Nevertheless, your error message sounds like you try to add an not existing object?