Preview usually works fine with environment object but I'm having trouble when accessing within the object an array of objects.
The following view doesn't show in preview but works fine insimulator
import SwiftUI
struct ScoreCell: View {
@EnvironmentObject var game : Game
var player: Player
var body: some View {
VStack {
Text(String(self.game.playerScores[self.game.indexOfPlayerInScores(player: player)].totalScore()))
}
}
}
struct ScoreCell_Previews: PreviewProvider {
static var previews: some View {
ScoreCell(player: Player(name: "s", shortName: "Steph", photoURL: "steph", color: Color(.cyan)))
.environmentObject(Game())
}
}
If I replace by a hardcoded index it works just fine (like in the line below)
Text(String(self.game.playerScores[0].totalScore()))
Additional info:
struct PlayerScore {
let player: Player
var pointsList: [Int]
func totalScore() -> Int {
return pointsList.reduce(0, +)
}
}
I can definitely work without preview but I have the feeling it's hiding a more generic problem that will bite me later ... Thanks for the help.
Adding code of Game to provide potential info - Thanks
import SwiftUI
import Combine
class Game: ObservableObject {
var players = [Player] ()
@Published var playerScores = [PlayerScore] ()
func addPlayer(player: Player) {
players.append(player)
playerScores.append(PlayerScore(player: player, pointsList: [0]))
}
func addPlayer(player: Player, score: Int) {
players.append(player)
playerScores.append(PlayerScore(player: player, pointsList: [score]))
}
func indexOfPlayerInScores(player: Player) -> Int {
return playerScores.firstIndex(where: {$0.player.id == player.id})!
}
init () {
self.addPlayer(player: Player(name: "Stephane", shortName: "Steph", photoURL:"steph", color: Color(.sRGB,red: 90/255, green: 197/255, blue: 191/255)))
self.addPlayer(player: Player(name: "Sophie", shortName: "Sof", photoURL:"sof", color: Color(.sRGB, red: 189/255, green: 0/255, blue: 82/255)))
self.addPlayer(player: Player(name: "Chloe", shortName: "Chloe", photoURL:"chloe", color: Color(.sRGB,red: 251/255, green: 78/255, blue: 84/255)))
self.addPlayer(player: Player(name: "Stephane", shortName: "Gaby", photoURL:"gaby", color: Color(.sRGB,red: 255/255, green: 195/255, blue: 11/255)))
}
}
The issue is definitely here
func indexOfPlayerInScores(player: Player) -> Int {
return playerScores.firstIndex(where: {$0.player.id == player.id})!
}
you Player
does not have id
in constructor, so it is autogenerated, so above method just does not find matches in run-time, because created player in preview and added by-default players in Game
are different (independently of type, class or struct).
The solution: to change logic of detecting equality of Players (maybe confirming explicitly to Equatable).