问题描述
我已经为此苦苦挣扎了一段时间。它让我彻夜难眠,让我害怕早上起床。 我有一个 SwiftUI ContentView,我从中调用了一个名为 GameScene 的 SpriteKit 场景。 游戏结束后,我想用分数更新 ContentView。 事实证明,这比我想象的要困难得多。 我已经尝试过@EnvironmentObject、@Bindings、(等)UserDefaults、userData(在 SK 场景中)......将数据传递给 GameScene 很简单,但是如何让 ContentView 在得分时更新(重绘自身)变化? 我知道我们应该展示示例代码,但坦率地说,我已经尝试了很多次和很多方法,我不知道从哪里开始。如果有人可以向我保证这是可能的(首先)并且可能会指出我正确的方向,我将不胜感激! (并承诺在找到解决方案时分享我的解决方案。)谢谢! 这是我的 ObservableObject 类:
final class GameTracker: ObservableObject {
@Published var items: [CompletedChallenge] = []
var totalscore: Int {
items.reduce(0) {$0 + $1.points}
}
func add(_ completedItem: CompletedChallenge) {
items.append(completedItem)
}
}
}
ContentView 是这样的:
struct ContentView: View {
@EnvironmentObject var game: GameTracker
var body: some View {
vstack{
NavigationView {
List{
ForEach(selectedChallenges) { challenge in
NavigationLink(
destination: DetailView(challenge: challenge)
) {
HStack{
Image(systemName: game.items.contains { item in
item.challenge == challenge }
? "checkmark.circle.fill" : "arrowtriangle.right.circle")
.foregroundColor(.orange)
Text(challenge.name)
Spacer()
}
}
}
}
.navigationBarTitle(Text("Challenges"))
}
Text("score: \(game.totalscore)")
}
}
}
在此示例中,所选列表项导航到 DetailView,我可以在其中更新 ObservableObject:
@EnvironmentObject var game: GameTracker
...
let newItem = CompletedChallenge(challenge: challenge,points: challenge.maxPoints)
game.add(newItem)
当一切都在 SwiftUI 视图中时,这很有效。但是当我从 SpriteKit GameScene 调用 game.add(newItem) 时,我无法得到相同的结果。
解决方法
您的 totalScore
属性不是 @Published
,因此 SwiftUI 视图不会在值更改时更新。
试试这个:
final class GameTracker: ObservableObject {
@Published var items: [CompletedChallenge] = []
@Published var totalScore: Int { // <-- Here!
items.reduce(0) {$0 + $1.points}
}
func add(_ completedItem: CompletedChallenge) {
items.append(completedItem)
}
}
}