Home > Enterprise >  Why my arrow shortcuts don't work after I apply a custom ButtonStyle in SwiftUI?
Why my arrow shortcuts don't work after I apply a custom ButtonStyle in SwiftUI?

Time:05-22

Built for macOS 12. After I use my custom ButtonStyle like below. The arrow KeyboardShortcut won't work, but other shortcuts like space or return or directly click work fine.

// CustomButtonStyle.swift

struct PlayerButton: ButtonStyle {
    
    @State private var onHover: Bool = false
    @State private var isPressed: Bool = false
    
    var foreground: Color {
        if isPressed {
            return .primary
        } else {
            return .secondary
        }
    }
    
    var background: AnyShapeStyle {
        if isPressed {
            return AnyShapeStyle(.ultraThickMaterial)
        } else if onHover {
            return AnyShapeStyle(.ultraThinMaterial)
        } else {
            return AnyShapeStyle(.background)
        }
    }

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(foreground)
            .frame(width: 32, height: 28, alignment: .center)
            .background(background)
            .cornerRadius(5)
            .onHover { onHover in
                self.onHover = onHover
            }
            .onChange(of: configuration.isPressed) { isPressed in
                self.isPressed = isPressed
            }
    }
    
}
// ContenView.swift

struct ContentView: View {
    var body: some View {
        
        // Work fine
        Button("Button 1") {
            print("1")
        }
        .buttonStyle(PlayerButton())
        .keyboardShortcut(.space, modifiers: [])
        
        // Work fine
        Button("Button 2") {
            print("2")
        }
        .keyboardShortcut(.upArrow, modifiers: [])
        
        //Doesn't work
        Button("Button 3") {
            print("3")
        }
        .buttonStyle(PlayerButton())
        .keyboardShortcut(.downArrow, modifiers: [])
    }
}

CodePudding user response:

Looks like a SwiftUI bug. Here is possible safe workaround (tested with Xcode 13.3 / macOS 12.3.1)

Here is main part:

        ZStack {
            Button("", action: button3action)
                .opacity(0)
                .keyboardShortcut(.downArrow, modifiers: [])
            Button("Button 3", action: button3action)
                .buttonStyle(PlayerButton())
        }

    // ...

    func button3action() {
        print("3")
    }

Complete test module in project

  • Related