I've run into a similar issue (xCode 12.5.1, iOS 14):
I've built the tiny app below, to reproduce this: a Game class that can increment a counter, and a GameView that calls this functionality. Nothing else. The ContentView 'owns' the Game class and passes it to the GameView in its NavigationLink. This works flawlessly, unless:
There are exactly two links in the ContentView (which I saw others mention)
At least one of them is bound to a @State var with tag/selection (even if it doesn't use it :/ )
In that case clicking the "Increment Count" button will pop the view. Removing the tag/selection from the second link, or adding the EmptyView will both fix it:
struct ContentView: View {
@StateObject var game = Game()
@State var action: Int? = 0
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: GameView(game: game)) {
Text("Link 1")
}
NavigationLink(destination: Text("Useless View"), tag: 1, selection: self.$action) {
Text("Useless Link")
}
//NavigationLink(destination: EmptyView()) {
// EmptyView()
//}
}
}
}
}
struct GameView: View {
@ObservedObject var game: Game
var body: some View {
VStack{
Text("Count: \(game.count)")
Button("Increment Count") {
game.incrementCount()
}
}
}
}
class Game: ObservableObject {
@Published var count: Int = 0
func incrementCount() {
count += 1
}
}