So I am working on a phase10 scoreboard app. When you open the app you see a list of games, then you can click on the game and see the players and their scores as well as the rounds that have been logged for the game. When you click on the round I have a tab view that lets you scroll through each player and a stepper that lets you set the points that the player earned for that round. The problem I am having is that when I click on the stepper it closes the view and goes back to the game view. I tried a test with a custom stepper (just a hstack with text and two buttons) but got the same results. So I believe that it is an issue with updating the Round model object but I have no clue what or even how to trace it. It gives me no printout or errors just closes the view and goes back to the game view.
PS: I know that I will get yelled at for copying to much code here, but the last time I posted a question about this app I didn't post stuff and they needed that to compile so that they could recreate. So I just loaded it all its a pretty small app so far. I apologize for the inconvenience but I have no idea which components you would need to debug.
import SwiftUI
@main
struct Phase10App: App {
@ObservedObject var viewModel = ApplicationViewModel()
var body: some Scene {
WindowGroup {
GamesView()
.environmentObject(self.viewModel)
}
}
}
class ApplicationViewModel: ObservableObject {
@Published var games: [Game] = []
init() {
loadDemo()
}
func loadDemo() {
for g in 0...3 {
var game = Game(name: "Demo Game #\(g)")
for p in 0...3 {
game.players.append(Player(name: "Player #\(g):\(p)"))
}
self.games.append(game)
}
}
}
struct Game: Identifiable, Codable {
var id: UUID = UUID()
init(name: String) {
self.name = name
}
var name: String
var currentRound: Int = 1
var players: [Player] = []
}
struct Player: Identifiable, Codable {
var id: UUID = UUID()
init(name: String) {
self.name = name
}
var name: String
var rounds: Array<Round> = Array(repeating: Round(), count: 100)
}
extension Player {
var score: Int {
return self.rounds.map({$0.earnedPoints}).reduce(0, +)
}
}
struct Round: Identifiable, Codable {
var id: UUID = UUID()
var earnedPoints: Int = 0
var selectedPhase: Int = 1
var completedPhase: Bool = false
}
struct GamesView: View {
@EnvironmentObject var viewModel: ApplicationViewModel
var body: some View {
NavigationView {
List {
Section("GAMES") {
ForEach(self.viewModel.games.indices) { game in
NavigationLink(
self.viewModel.games[game].name,
destination:
GameView(
game: Binding<Game>(
get: {self.viewModel.games[game]},
set: {self.viewModel.games[game]=$0}
)
)
)
}
.onDelete(perform: onDelete)
}
}
.navigationTitle("Phase 10")
}
}
func onDelete(at offsets: IndexSet) {
self.viewModel.games.remove(atOffsets: offsets)
}
}
struct GameView: View {
@Binding var game: Game
var body: some View {
List {
Section("PLAYERS") {
ForEach(game.players) { player in
HStack {
Text(player.name)
Spacer()
Text("\(player.score)")
}
}
}
Section("ROUNDS") {
ForEach(0..<game.currentRound) { round in
NavigationLink(
"Round #\(round+1)",
destination: View1(game: $game, currentRound: round)
)
}
}
}
.navigationTitle(game.name)
}
}
struct View1: View {
@Binding var game: Game
@State var currentRound: Int
var body: some View {
TabView {
ForEach(game.players.indices) { player in
View1a(
player: game.players[player],
round: Binding<Round> (
get: {game.players[player].rounds[currentRound]},
set: {game.players[player].rounds[currentRound] = $0}
)
)
}
}
.tabViewStyle(PageTabViewStyle())
.navigationTitle("Round #\(currentRound+1)")
}
}
struct View1a: View {
@State var player: Player
@Binding var round: Round
var body: some View {
VStack {
Text(player.name).font(.title)
Divider()
Group {
Stepper(
"# of Points: \(self.round.earnedPoints)",
value: self.$round.earnedPoints,
in: 0...250,
step: 5
)
}
.padding(.horizontal, 50)
}
}
}