Reputation: 2271
I'm having an issue in preview mode only because of the way I initialise one of my variables. This view takes a PlayerScore as parameter because I need to know which score to edit. It also has the game enviroment object where all scores are stored.
What I do is simple, I search the index of the playerscore in the game array of PlayerScores in order to later modify it.
Problem with preview is that the PlayerScore I use in the ScoreEntry_Previews is obviously not matching the UUID of the playerScore in the game array. So it won't render the preview because the var initialisation fails as it doesn't find the UUID.
How do I deal with that ?
struct ScoreEntry: View {
@EnvironmentObject var game : Game
@Binding var isPresented: Bool
var playerScore: PlayerScore
var scoreIndex: Int {
game.playerScores.firstIndex(where: { $0.id == playerScore.id})!
}
var body: some View {
HStack {
Text("\(self.game.playerScores[self.scoreIndex].totalScore())")
}
}
}
struct ScoreEntry_Previews: PreviewProvider {
static var previews: some View {
ScoreEntry(
isPresented: .constant(true)
,playerScore: PlayerScore(player: Player(name: "SomePlayer", shortName: "Steph", photoURL:"steph", color: .orange),pointsList: [1,2])
).environmentObject(Game())
}
}
struct PlayerScore: Identifiable, Hashable {
var id = UUID()
let player: Player
var pointsList: [Int]
func totalScore() -> Int {
return pointsList.reduce(0, +)
}
mutating func addPoints(scoreValue: Int) {
pointsList.append(scoreValue)
}
}
class Game: ObservableObject {
var players = [Player] ()
@Published var playerScores = [PlayerScore] ()
}
Upvotes: 1
Views: 91
Reputation: 257703
Don't auto-generate id
internally, instead make it injectable, so you can create one in Preview and inject same in both places
struct PlayerScore: Identifiable, Hashable {
var id: UUID // << require external
Update: actually the above is still be possible approach, but below is alternate approach w/o changes in UUID.
Tested with Xcode 11.4 / iOS 13.4
Full tested module code
struct Player {
var name: String
var shortName: String
var photoURL: String
var color: Color
}
struct PlayerScore: Identifiable {
var id = UUID()
let player: Player
var pointsList: [Int]
func totalScore() -> Int {
return pointsList.reduce(0, +)
}
mutating func addPoints(scoreValue: Int) {
pointsList.append(scoreValue)
}
}
class Game: ObservableObject {
var players: [Player]
@Published var playerScores: [PlayerScore]
init(players: [Player] = [], scores: [PlayerScore] = []) {
self.players = players
self.playerScores = scores
}
}
struct ScoreEntry: View {
@EnvironmentObject var game : Game
@Binding var isPresented: Bool
var playerScore: PlayerScore
var scoreIndex: Int {
game.playerScores.firstIndex(where: { $0.id == playerScore.id})!
}
var body: some View {
HStack {
Text("\(self.game.playerScores[self.scoreIndex].totalScore())")
}
}
}
struct ScoreEntry_Previews: PreviewProvider {
static var previews: some View {
let score = PlayerScore(player: Player(name: "SomePlayer", shortName: "Steph", photoURL:"steph", color: .orange), pointsList: [1, 2])
return ScoreEntry(isPresented: .constant(true), playerScore: score)
.environmentObject(Game(scores: [score]))
}
}
Upvotes: 1