Swift中点击NavigationLink重复生成相同Board的问题求助
解决数独游戏重复生成相同棋盘的问题
问题根源
你遇到的问题本质是:从WelcomeView进入GameView时,复用了提前创建好的旧Board实例,而GameView内的新游戏是实时生成新实例,导致两次进入同难度得到重复棋盘。
具体解决步骤
1. 重构Board的初始化逻辑
给Board添加按难度生成棋盘的初始化方法,确保每次初始化都生成全新的棋盘:
// 先定义难度枚举 enum Difficulty { case easy, medium, hard } struct Board { let id = UUID() // 加UUID用于标识不同实例,辅助视图刷新判断 var grid: [[Int]] // 按难度初始化,直接生成对应棋盘 init(difficulty: Difficulty) { self.grid = Self.generateGrid(for: difficulty) } // 静态方法:根据难度生成棋盘逻辑 static func generateGrid(for difficulty: Difficulty) -> [[Int]] { // 这里替换成你的数独棋盘生成代码,根据难度调整空位数量/位置等 switch difficulty { case .easy: return generateEasyGrid() case .medium: return generateMediumGrid() case .hard: return generateHardGrid() } } // 你的具体生成函数 private static func generateEasyGrid() -> [[Int]] { /* ... */ } private static func generateMediumGrid() -> [[Int]] { /* ... */ } private static func generateHardGrid() -> [[Int]] { /* ... */ } }
2. 修改GameView:接收难度参数,实时生成Board
让GameView不再直接接收Board实例,而是接收难度,初始化时创建新的Board:
struct GameView: View { let difficulty: Difficulty @State private var currentBoard: Board // 初始化时根据难度生成新棋盘 init(difficulty: Difficulty) { self.difficulty = difficulty self._currentBoard = State(initialValue: Board(difficulty: difficulty)) } // 游戏内切换同难度新游戏的逻辑 private func startNewGame() { currentBoard = Board(difficulty: difficulty) } var body: some View { VStack { // 渲染81个CellView,使用currentBoard.grid ForEach(0..<9) { row in HStack { ForEach(0..<9) { col in CellView(value: currentBoard.grid[row][col]) } } } Button("同难度新游戏") { startNewGame() } } } }
3. 调整WelcomeView的NavigationLink
不要提前生成Board实例,而是直接给GameView传难度参数:
struct WelcomeView: View { var body: some View { NavigationStack { VStack(spacing: 20) { NavigationLink("开始Easy难度", destination: GameView(difficulty: .easy)) NavigationLink("开始Medium难度", destination: GameView(difficulty: .medium)) NavigationLink("开始Hard难度", destination: GameView(difficulty: .hard)) } .padding() } } }
为什么之前加UUID没用?
你给Board加UUID是对的,但问题出在没有创建新实例——如果WelcomeView里提前生成了一个Easy难度的Board并缓存,每次点击NavigationLink都传这个旧实例,UUID虽然存在,但还是同一个对象,棋盘自然不会变。现在的逻辑是每次进入GameView都创建全新的Board实例,UUID也会是新的,视图会自动刷新显示新棋盘。
内容的提问来源于stack exchange,提问作者b3rber
相关产品推荐
相关产品推荐

