skip to Main Content

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

2

Answers


  1. 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

    Login or Signup to reply.
  2. 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 {
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search