【问题标题】:Passing Data from SpriteKit Scene back to SwiftUI将 SpriteKit 场景中的数据传回 SwiftUI
【发布时间】:2021-06-04 19:23:44
【问题描述】:

我已经为此苦苦挣扎了一段时间。它让我晚上睡不着,让我害怕早上起床。 我有一个 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) 时,我无法得到相同的结果。

【问题讨论】:

  • 所以在这里输入没有代码的单词也无济于事。
  • @Hyoryusha 我相信GameScene 在你的情况下就像model,让它确认ObservableObject 协议,在你的内容视图中实例化该模型的StateObject 。正如您所说,您只想在游戏结束后刷新ContentView,您可以在模型类中创建一个propertyObserver,观察游戏状态的变化,并在该属性中使用self.objectWillChange.send(),这将触发变化在你的游戏完成状态变为真之后。
  • @TusharSharma,感谢您的建议(以及之前对 SO 的帮助)。但我仍然有麻烦。我在原始问题中添加了示例代码,希望能澄清情况。

标签: swiftui sprite-kit


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    相关资源
    最近更新 更多