SwiftUI SpriteView中如何传递鼠标滚轮事件至SKScene?
解决MacOS SwiftUI中SpriteKit场景滚轮事件不触发的问题
在SwiftUI的SpriteView容器中,MacOS下SKScene的scrollWheel(with:)方法无法触发——此前Cocoa环境中通过设置SKScene为nextResponder的方式能解决,但SwiftUI的视图响应链逻辑不同,需要通过自定义SKView包装器来处理事件传递。
解决方案1:自定义NSViewRepresentable包装SKView并设置响应链
创建替代默认SpriteView的自定义包装器,手动将SKScene设置为SKView的下一个响应者:
import SwiftUI import SpriteKit struct CustomSpriteView: NSViewRepresentable { let scene: SKScene func makeNSView(context: Context) -> SKView { let skView = SKView() skView.presentScene(scene) // 将场景设置为SKView的nextResponder,让滚轮事件能传递至场景 skView.nextResponder = scene return skView } func updateNSView(_ nsView: SKView, context: Context) {} }
在你的ContentView中,用CustomSpriteView(scene: chartScene)替代原来的SpriteView即可。
解决方案2:重写SKView的滚轮事件主动转发
如果方案1因SwiftUI视图层级变化导致响应链中断,可以通过自定义SKView子类,主动将滚轮事件转发给当前场景:
import SwiftUI import SpriteKit class ForwardingSKView: SKView { override func scrollWheel(with event: NSEvent) { super.scrollWheel(with: event) // 直接将滚轮事件传递给当前显示的场景 scene?.scrollWheel(with: event) } } struct CustomSpriteView: NSViewRepresentable { let scene: SKScene func makeNSView(context: Context) -> ForwardingSKView { let skView = ForwardingSKView() skView.presentScene(scene) return skView } func updateNSView(_ nsView: ForwardingSKView, context: Context) {} }
同样在ContentView中替换使用CustomSpriteView。
代码修改说明
你的原主入口代码无需调整,只需要把ContentView中使用的SpriteView替换为上述自定义版本,就能让ChartScene中的scrollWheel(with:)方法正常接收滚轮事件,效果和你之前在Cocoa中的实现一致。
内容的提问来源于stack exchange,提问作者BDub
相关产品推荐
相关产品推荐

