Removing the error sound on keydown macOS

I'm making a macOS app with SwiftUI. I would like the window to listen for keyboard events, and to determine which key was pressed. The problem I have now is that app plays the 'funk' error sound every time I hit a key, but other than that it works fine. How do I get it to stop playing the sound?


This is my code, which I found online:


struct KeyEventHandling: NSViewRepresentable {
    
    class KeyView: NSView {
        override var acceptsFirstResponder: Bool { true }
        override func keyDown(with event: NSEvent) {
            super.keyDown(with: event)
            print(">> key \(event.keyCode)")
        }
    }
    
    func makeNSView(context: Context) -> NSView {
        let view = KeyView()
        DispatchQueue.main.async { // wait till next event cycle
            view.window?.makeFirstResponder(view)
        }
        return view
    }
    
    func updateNSView(_ nsView: NSView, context: Context) {
    }
    
}

struct ContentView: View {
    var body: some View {
        KeyEventHandling()
    }
}


The code prints each keyCode correctly, the only issue is the error sound that it plays. There are similar questions on Stack Overflow, but those are using pure AppKit with view controllers, so how do I implement it here, in SwiftUI?


Thanks!

Accepted Reply

You usually do not call `super.keyDown(with: event)` when the key event is processed by the view itself.

    class KeyView: NSView {
        func isManagedByThisView(_ event: NSEvent) -> Bool {
            //...
            return true
        }
        
        override var acceptsFirstResponder: Bool { true }
        override func keyDown(with event: NSEvent) {
            if isManagedByThisView(event) {
                print(">> key \(event.keyCode)")
            } else {
                super.keyDown(with: event)
            }
        }
    }


When you call `super.keyDown(with: event)`, the event goes up through the responder chain and if no other responders process it, causes beep sound.

Replies

You usually do not call `super.keyDown(with: event)` when the key event is processed by the view itself.

    class KeyView: NSView {
        func isManagedByThisView(_ event: NSEvent) -> Bool {
            //...
            return true
        }
        
        override var acceptsFirstResponder: Bool { true }
        override func keyDown(with event: NSEvent) {
            if isManagedByThisView(event) {
                print(">> key \(event.keyCode)")
            } else {
                super.keyDown(with: event)
            }
        }
    }


When you call `super.keyDown(with: event)`, the event goes up through the responder chain and if no other responders process it, causes beep sound.