Предварительный просмотр холста не отображается при доступе к environmentObject, содержащему массив объектов - PullRequest
1 голос
/ 23 марта 2020

Предварительный просмотр обычно работает нормально с объектом окружения, но у меня возникают проблемы при доступе к объекту массива объектов.

Следующий вид не отображается в предварительном просмотре, но прекрасно работает с имитатором

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())
    }
}

Если я заменю на жестко закодированный индекс, он будет работать нормально (как в строке ниже)

Text(String(self.game.playerScores[0].totalScore()))

Дополнительная информация:

  • var "player" работает нормально в другой строке представления
  • playerScores - это массив playerScore, определенный следующим образом:
struct PlayerScore {
    let player: Player
    var pointsList: [Int]     


    func totalScore() -> Int {
        return pointsList.reduce(0, +)
    }
}

Я могу определенно работать без предварительного просмотра, но у меня такое ощущение, что он скрывает более обобщенные c проблема, которая будет кусать меня позже ... Спасибо за помощь.

Добавление кода Game для предоставления потенциальной информации - Спасибо

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)))
    }


}

1 Ответ

1 голос
/ 23 марта 2020

Проблема определенно здесь

func indexOfPlayerInScores(player: Player) -> Int {
    return  playerScores.firstIndex(where: {$0.player.id == player.id})!
}

у вас Player нет id в конструкторе, поэтому он генерируется автоматически, поэтому вышеуказанный метод просто не находит совпадений во время выполнения, потому что создан player в предпросмотре и добавленные по умолчанию игроки в Game различаются (независимо от типа, класса или структуры).

Решение: изменить логику c обнаружения равенства игроков (может быть подтверждено явно Equatable).

...