Home > other >  iOS game development: how do I use NavigationView buttons to call a function from another class?
iOS game development: how do I use NavigationView buttons to call a function from another class?

Time:01-10

I'm brand new to Swift programming, and have pulled together a couple tutorials to try to make a simple Minesweeper iOS app. I want to have a menu at the bottom with an option to reset the board. I have a function in Game.swift that resets the board, and the main navigation is in MinesweeperApp.swift. I can't figure out how to call the reset function from the navigation without getting an error.

My project structure is as such:

Minesweeper
  ├ View
  | ├ CellView.swift
  | └ BoardView.swift
  ├ Model
  | ├ GameSettings.swift
  | ├ Game.swift
  | ├ Cell.swift
  | └ Cell Swift.swift
  ├ Shared
  | ├ Assets.xcassets
  | ├ MinesweeperApp.swift
  | └ ContentView.swift

My Game.swift file:

class Game: ObservableObject {
    
    // the game settings
    @Published var settings: GameSettings
    @Published var board: [[Cell]]
    
    init(from settings: GameSettings) {
        self.settings = settings
        self.board = Game.GenerateBoard(from: settings)
    }

    ... etc ...

    func resetBoard() {
        self.board = Game.GenerateBoard(from: settings)
    }

My MinesweeperApp.swift file:

@main
struct MinesweeperApp: App {
    var gameSettings = GameSettings() // the game settings
    
    var body: some Scene {
        
        WindowGroup {
            NavigationView {
                BoardView() // our content view
                    .environmentObject(Game(from: gameSettings)).padding()
                    .navigationTitle("Minesweeper")
                    .toolbar {
                        ToolbarItem(placement: .bottomBar) {
                            Button("Reset") {
                                Game.resetBoard()
                                print("Pressed")
                            }
                        }
                    }
            }

        }
    }
}

When I take out the line Game.resetBoard() in MinesweeperApp, it works correctly and prints 'pressed'. When I add that line in, the error I'm getting says

Instance member 'resetBoard' cannot be used on type 'Game'; did you mean to use a value of this type instead?

So, I'm trying to figure out how/where to call the reset function correctly.

The tutorials I used are

CodePudding user response:

Right now, because you're creating your instance of Game inside the environmentObject call, you don't have a reference stored at the App level to manipulate.

The easiest fix would be this:

@main
struct MinesweeperApp: App {
    var game = Game(from: GameSettings())
    
    var body: some Scene {
        
        WindowGroup {
            NavigationView {
                BoardView() // our content view
                    .environmentObject(game)
                    .padding()
                    .navigationTitle("Minesweeper")
                    .toolbar {
                        ToolbarItem(placement: .bottomBar) {
                            Button("Reset") {
                                game.resetBoard() //<-- Here
                                print("Pressed")
                            }
                        }
                    }
            }

        }
    }
}

Then, you can call resetBoard on the instance of Game rather than trying to call it on the type (which is why you're getting the error right now).

This, of course, would depend on your sub views (like Board) using @EnvironmentObject var game : Game instead of @EnvironmentObject var gameSettings : GameSettings. And, you would access the settings in your subviews by doing game.settings

CodePudding user response:

Game = Class Game which cannot call non-static functions. You need to create Object before using ".resetBoard()" and I think it will be on top of your MinesweeperApp.

struct MinesweeperApp: App {
var gameSettings = GameSettings() // the game settings

//...
var game = Game(from settings: gameSettings)

var body: some Scene {
  •  Tags:  
  • Related