将数据从 SpriteKit 场景传回 SwiftUI [英] Passing Data from SpriteKit Scene back to SwiftUI

查看:24
本文介绍了将数据从 SpriteKit 场景传回 SwiftUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为此苦苦挣扎了一段时间.它让我彻夜难眠,让我害怕早上起床.我有一个 SwiftUI ContentView,我从中调用了一个名为 GameScene 的 SpriteKit 场景.游戏结束后,我想用分数更新 ContentView.事实证明,这比我想象的要困难得多.我已经尝试过@EnvironmentObject、@Bindings、(等)UserDefaults、userData(在 SK 场景中)......将数据传递给 GameScene 很简单,但是如何让 ContentView 在得分时更新(重绘自身)变化?我知道我们应该展示示例代码,但坦率地说,我已经尝试了很多次和很多方法,我不知道从哪里开始.如果有人可以向我保证这是可能的(首先)并且可能会指出我正确的方向,我将不胜感激!(并承诺在我找到解决方案时分享我的解决方案.)谢谢!这是我的 ObservableObject 类:

I've been struggling with this for a while. It's keeping me up at night and making me afraid to get out of bed in the mornings. I have a SwiftUI ContentView from which I call a SpriteKit Scene called GameScene. After the game is finished, I want to update ContentView with the score. This has proven to be much harder than I would have thought. I've tried @EnvironmentObject, @Bindings, (etc.) UserDefaults, userData (in SK scene)... It's simple enough to pass data TO the GameScene, but how can I get ContentView to update (redraw itself) when the score changes? I know we are supposed to show sample code, but, frankly, I've tried this so many times and so many ways, I wouldn't know where to start. If someone could assure me that this is possible (in the first place) and maybe point me in the right direction I'll be enormously grateful! (And promise to share my solution if and when I find one. ) Thanks! Here is my ObservableObject class:

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 是这样的:

ContentView is like this:

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:

In this example, the selected list item navigates to DetailView, where I am able to update the ObservableObject with this:

@EnvironmentObject var game: GameTracker


 ...
        let newItem = CompletedChallenge(challenge: challenge, points: challenge.maxPoints)
        game.add(newItem)

当一切都在 SwiftUI 视图中时,这很有效.但是当我从 SpriteKit GameScene 调用 game.add(newItem) 时,我无法得到相同的结果.

This works great when everything is in SwiftUI views. But I cannot get the same results when I call game.add(newItem) from a SpriteKit GameScene.

推荐答案

您的 totalScore 属性不是 @Published,因此 SwiftUI 视图不会更新该值变化.

Your totalScore property is not @Published, so the SwiftUI view won't update when the value changes.

试试这个:

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)
   }
}
}

这篇关于将数据从 SpriteKit 场景传回 SwiftUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆