You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:55:24