UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Day 91: Flashzilla challenge #3

Forums > 100 Days of SwiftUI

Regarding the Challenge #3: when the users gets an answer wrong, add that card goes back into the array so the user can try it again here. I'm getting a weird runtime error now like so:

Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem.

I added a symbolic breakpoint on CGPostError and it appears to be happening in EditCards view while typing in a TextField for the new prompt/question. I don't understand why I'd be getting a NAN there. I think it may have something to do with me adding a var id: UUID property to the Card struct, but I haven't tried to create a new Card etc. yet. I'm just typing in a field created by TextField("Question", text: $prompt)

No idea why I'm getting this and would appreciate any insight. TIA!

4      

I just received this error on a different project. Did you ever figure out what the problem was?

2      

@jimbo and @steer are stuck

@steer: I'm getting a weird runtime error
@Jimbo: Did you ever figure out what the problem was?

@twoStraws provides a subtle hint:

For a harder challenge: when the users gets an answer wrong, add that card
back into the array so the user can try it again.
HINT: Doing this successfully means rethinking the ForEach loop,
HINT: because relying on simple integers isn’t enough –
HINT: your cards need to be uniquely identifiable.

This challenge exposes you to a common problem when generating views via a ForEach factory.

I like to think of ForEach as a view factory!
See -> View Factory
or See -> View Factory
or See -> View Factory

Ask yourself: What is my ForEach view factory trying to make?

This is a simple example, the ForEach just generates five text views.

ForEach(0..<deckOfCards.count-1) { index in
    // The objects are identified by their PLACE in the array.
    Text("Object # \(deckOfCards[index].name)") // View factory generates 5 Text views.
}

Notice in this example the objects are identified by their PLACE in the array. If you delete the second card (index = 1) the deckOfCards will have one less card, but will still have a card at index 1. The array re-numbers its contents.

But when you use ForEach to generate views containing objects, it's imporant for SwiftUI to have the ability to identify WHICH object is tapped, or deleted.

ForEach( deckOfCards ) { card in 
    // Advanced Topic. 
    // User may want to select or delete this card. 
    // SwiftUI needs to know which card!
    PlayingCardView( for: card )  // <- BUILD a view for each card in the deck
}

Back of the Envelope Idea

If you select the Deuce of Clubs and remove it from the array named deckOfCards, how does SwiftUI know WHICH card to delete? If the card struct conforms to the identifiable protocol, each card will have a unique id property.

Consider how you might >save< this card to a holding area (another array named tryAgainDeck?). After the player goes through all the cards in the quiz, the game will cycle through the tryAgainDeck, and add those cards back into the deckOfCards array.

These are some random ideas. Neither of you showed code, so it's difficult to know how you approached this challenge.

Keep Coding

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.