使用 UIViewRepresentable

问题描述

很抱歉重复之前的(更详细的)问题,但我还没有解决这个问题。 我的目标: 我有一个名为 ContentView() 的 SwiftUI 视图。 它显示一个名为 GameScene 的 SpriteKit 场景以及一个带有 totalscore 属性的 Text() 视图。我希望 totalscore 来自名为 GameTracker 的 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)
        }
    }

我希望能够在 GameScene 中更改时更新 ContentView() 中的 totalscore

根据我在较早的帖子 (Passing Data from SpriteKit Scene back to SwiftUI) 中收到的答案,我尝试将 GameScene 设为 ObservableObject,并带有 @Published 变量,该变量将在 ContentView 中使用 @StateObject 读取。 这不起作用(尽管我承认我可能误解了该建议并错误地实施了它。)

然后我尝试像这样使用@EnvironmentObject(仅显示相关行):

class GameScene: SKScene {
    @EnvironmentObject var game: GameTracker
    ...
    let newItem = CompletedChallenge(challenge: challenge,points: challenge.maxPoints)
    game.add(newItem)
}

这会在模拟器中崩溃,并显示“致命错误:未找到 GameTracker 类型的 ObservableObject。GameTracker 的 View.environmentObject(_:) 可能缺少作为此视图的祖先。”

没有太多信心,我修改了对视图的调用,如下所示:

SpriteView(scene: scene)
    .environmentObject(game)

我决定放弃 SpriteView() 并改用 UIViewRepresentable。 这是 ContentView 中的新调用,传入一个@Binding

@State var game = GameTracker()
...
SpriteKitContainer(scene: scene,game: self.$game)
                .ignoresSafeArea()

这是 UIViewRepresentatble 的子类:

struct SpriteKitContainer: UIViewRepresentable {
    
    @Binding var game : GameTracker
    
    var skScene: SKScene!
    
    init(scene: SKScene,game: Binding<GameTracker>) {
        _game = game
        skScene = scene
        self.skScene.scaleMode = .resizefill
    }
    
    class Coordinator: NSObject {
        
        @Binding var game: GameTracker
        init(game: Binding<GameTracker>) {
            _game = game
        }
        var scene: SKScene?
    }
    
    func makeCoordinator() -> Coordinator {
        let coordinator = Coordinator(game: $game)
        coordinator.scene = self.skScene
        return coordinator
    }
    
    func makeUIView(context: Context) -> SKView {
        let view = SKView(frame: CGRect(x: 0,y: 0,width: 380,height: 668))
        ...
        return view
    }
    
    func updateUIView(_ view: SKView,context: Context) {
        view.presentScene(context.coordinator.scene)
    }
}

这会编译并将我带到 GameScene。但它什么也不做。 在这一点上,我恳求完全无知。显然,我在 UIRepresentable 和 GameScene 中遗漏了一个步骤。但我在黑暗中。 对这么长的帖子深表歉意,并提前感谢任何可以提供帮助的人! 谢谢! ( + yoroshiku)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)