Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI onMoveCommand actions aren't executed

I'm making a macOS app with SwiftUI, and I would like to offset a SwiftUI view using the arrow keys on the built-in keyboard.

I couldn't find many resources online, but onMoveCommand() appears to be the event handler I need. Upon trying it out, I discovered that the action I specified for onMoveCommand() does not appear to be executed. Here's some code I wrote just to test it out:

struct ContentView: View {
    var body: some View {
        Text("Hello")
            .onAppear() {
                print("Appeared!")
            }
            .onMoveCommand() { (direction) in
                print("Moved!")
            }
            .onTapGesture() {
                print("Tapped!")
            }
    }
}

onMoveCommand() does not print "Moved!" when I press the arrow keys, instead I get the error alert sound played, and nothing is printed. onAppear() successfully prints the "Appeared!" message when the view appears, and onTapGesture() prints "Tapped!" correctly whenever I click the text. This seems to tell me that the basic syntax I got for these view events is correct, but I implemented onMoveCommand() incorrectly.

For now I only want my app to print something to the Xcode console when the arrow keys are pressed, and to be able to distinguish which arrow key was pressed. Can someone please explain what I did wrong?

like image 802
qitianshi Avatar asked Jun 25 '26 05:06

qitianshi


1 Answers

Keyboard events are handled only by view in focus, so fix is

var body: some View {
    Text("Hello")
        .focusable()         // << here !!
        .onAppear() {
            print("Appeared!")
        }
        .onMoveCommand() { (direction) in
            print("Moved!")
        }
        .onTapGesture() {
            print("Tapped!")
        }
}

Tested with Xcode 11.4 / macOS 10.15.4. Make sure you have turned on keyboard navigation in System Preferences.

demo

like image 96
Asperi Avatar answered Jun 26 '26 22:06

Asperi