Search code examples
macosswiftuisprite-kitskscenensevent

Listening for click/touch events in SKScene on MacOS in a SwiftUI SpriteView


I'm trying to intercept mouse click events inside SpriteKit SKScene inside a a SwiftUI SpriteView in Mac OS. Overriding touchesBegun() that accepts an NSEvent object is never called when I click mouse inside the view. isUserInteractionEnabled is set to true. What am I missing? Running in Xcode 13.2 with deployment target 12.1 for Mac OS.

import SwiftUI
import SpriteKit

class MyScene : SKScene {
    override func touchesBegan(with event: NSEvent) {
        print(event)
    }
}

var scene : MyScene {
    let r = MyScene()
    r.isUserInteractionEnabled = true
    r.size = .init(width: 500, height: 500)
    r.scaleMode = .aspectFill
    r.backgroundColor = .orange
    return r
}

struct ContentView: View {
    var body: some View {
        SpriteView.init(scene: scene)
            .frame(width: 500, height: 500)
            .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Solution

  • On macOS SKScene inherits from NSResponder, so we override mouse handlers, like

    class MyScene : SKScene {
        override func mouseDown(with event: NSEvent) {  // << here !!
            print(event)
        }
    }
    

    Tested with Xcode 14 / macOS 12.5