It's a little more complicated to explain, but basing everything off the code I've already provided... you have your cards
array in the main app:
func createData() {
// Two instances of the Card class are created here and added to the `cards` array
cards.append(Card.init(coord: Coordinate(latitude: gameArray[2], longitude: gameArray[3]), name: "Card1", threeWords: "london.is.great"))
cards.append(Card.init(coord: Coordinate(latitude: gameArray[2], longitude: gameArray[3]), name: "Card2", threeWords: "cheese.is.yummy"))
}
That's where your data is set up. It contains two cards right now, but you can expand it however you want.
Now you need to loop through those cards so you can add them to the UI, so in your ContentView
find this line towards the top:
@ObservedObject private var card: Card = cards.first(where: { $0.name == "Card1" }) ?? Card.emptyCard
You don't need it anymore so you can delete it, or you can leave it there for reference and simply comment it out if you like.
Change your VStack
to this:
ForEach(cards, id: \.self) { card in
VStack {
CoordEntryView(isLatitude: true, card: card)
Divider()
CoordEntryView(isLatitude: false, card: card)
Divider()
TextEntryView_ThreeWords(card: card)
}
.padding()
}
What you're doing there is putting the VStack
inside a ForEach
loop. ForEach
simply runs through the items in the cards
array, and each item is then referred to as card
(where it says card in
).
In order to use ForEach
, your Card
class has to be changed to be Hashable
. It is changed to become this:
class Card: ObservableObject, Hashable { // Note: Hashable added here
var uid = UUID().uuidString
@Published var coord: Coordinate
@Published var name: String
@Published var threeWords: String
static func == (lhs: Card, rhs: Card) -> Bool {
return lhs.uid == rhs.uid
}
func hash(into hasher: inout Hasher) {
hasher.combine(uid)
}
init(coord: Coordinate, name: String, threeWords: String) {
self.coord = coord
self.name = name
self.threeWords = threeWords
}
/*
This allows you to create an empty card, i.e. one with default values. You can do this in any of the following ways:
`var newCard: Card = Card.emptyCard`
`var newCard: Card = .emptyCard`
`var newCard = Card.emptyCard`
*/
static let emptyCard = Card(coord: Coordinate.zeroCoord, name: "", threeWords: "")
}
Basically, you add a unique identifier: var uid = UUID().uuidString
and you add a couple of methods that make it hashable.
Now, when you run the app, you should see both cards in the UI:
