导航链接问题:无法转换类型为"..."的值到预期的参数类型"..."



我正在尝试创建一个导航屏幕,该屏幕将提供两个按钮 - 一个转到有趣的小游戏,另一个转到向我显示随机图像的部分。我已经找到了导航链接功能,我可以让它正常工作,但我收到一个我不明白的错误。我已经查找了许多解决方案,但没有一个使用NavigationLink,所以我不确定如何实现我所阅读的内容。

其中一个按钮应导航到游戏,但导航链接给出错误:"无法将类型'GameViewModel.Type'的值转换为预期的参数类型'GameViewModel'">

如果我尝试删除"viewModel:GameViewModel",而是将其替换为正常的"选择:字符串",它会给出错误:"调用中缺少参数'viewModel'的参数",然后建议一个修复程序,只是将"viewModel:GameViewModel"放回原处,如下所示。

我不明白的是,这是想告诉我什么。我要做的就是让导航视图开始游戏,这是从顶部的"结构游戏视图:视图{"行。"var viewModel:GameViewModel"似乎存在某种问题,但我尝试将其放在其他地方,但无法使其工作。

如果我删除导航链接部分并让它启动游戏,它就可以工作。如果我删除导航链接部分并让它向我显示图片,它就可以工作。只是这个错误我不明白。

我将不胜感激任何帮助!在过去的一周左右的时间里,这个论坛真的帮助了我,非常棒!

更新的代码:

import SwiftUI
import Foundation
struct ContentView: View {
@State private var score = 0
var body: some View {
NavigationView {
Image("Clouds")
.overlay(
VStack {
NavigationLink(destination: ResultView2(choice: "Menu2")) {
Image("Menu2")
}
NavigationLink(destination: GameView(viewModel: GameViewModel(Engine.self as! Engine, storage: Storage.self as! Storage, stateTracker: StateTracker.self as! StateTracker))) {
Image("Menu")
}
})
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
struct GameView: View {
@ObservedObject var viewModel: GameViewModel
@State var showMenu = false
var body: some View {
VStack(alignment: .center, spacing: 16) {
Header(score: viewModel.state.score, bestScore: viewModel.bestScore, menuAction: {
self.showMenu.toggle()
}, undoAction: {
self.viewModel.undo()
}, undoEnabled: self.viewModel.isUndoable)
GoalText()
Board(board: viewModel.state.board, addedTile: viewModel.addedTile)
Moves(viewModel.numberOfMoves)
}
.frame(minWidth: .zero,
maxWidth: .infinity,
minHeight: .zero,
maxHeight: .infinity,
alignment: .center)
.background(Color.gameBackground)
.background(Menu())
.background(GameOver())
.edgesIgnoringSafeArea(.all)
}
}
extension GameView {
private func Menu() -> some View {
EmptyView().sheet(isPresented: $showMenu) {
MenuView(newGameAction: {
self.viewModel.reset()
self.showMenu.toggle()
}, resetScoreAction: {
self.viewModel.eraseBestScore()
self.showMenu.toggle()
})
}
}
private func GameOver() -> some View {
EmptyView().sheet(isPresented: $viewModel.isGameOver) {
GameOverView(score: self.viewModel.state.score, moves: self.viewModel.numberOfMoves) {
self.viewModel.reset()
}
}
}
}
struct ResultView2: View {
var choice: String
var body: some View {
Text("You chose Menu2")
}
}

在您的示例中,您正在传递GameViewModel,这似乎是一个class type。但是,GameView(viewModel:)采用GameViewModel类型的变量或GameViewModel的实例。

1. 第一个

在这种情况下,我们传递了一个GameViewModel的实例,所以代码看起来像这样:

你需要改变

NavigationLink(destination: GameView(viewModel: GameViewModel)) {

NavigationLink(destination: GameView(viewModel: GameViewModel())) {

上述解决方案将解决此问题,但由于您可能希望在父视图ContentView(在本例中)中使用GameViewModel实例(在本例中)GameView将其传递给子视图(在本例中),因此最好在父视图中存储一个实例变量GameViewModel,然后将其传递给子视图。 要演示这一点,请执行以下操作:

2. 第二种选择

在您的ContentView中,创建此类型为GameViewModel的实例变量:

@@bservedObject var gameViewModel = GameViewModel()

并像这样传递给GameView

NavigationLink(destination: GameView(viewModel: gameViewModel) {

最新更新