How to use isPressed property in PrimitiveButtonStyle?

I'm trying to create a button style that allows my buttons to 1)get triggered the moment when the finger taps on the button, so it's like UIButton's "touch down" instead of "touch up inside" 2)when the finger touches the button, the button becomes smaller and decreases its opacity, when the finger leaves the button, the button goes back to its original size and opacity.

I have managed to achieve the touch down effect using LongPressGesture. But I can't achieve the second desired effect where the button gets smaller and more transparent when my finger is touching the button. The code below does change the button size and opacity, but the problem is the button would revert back to its original size and opacity while my finger is still on the button.

There is a property in ButtonStyleConfiguration called isPressed which gives me the second desired effect. But I can't seem to use it while adopting the PrimitiveButtonStyle protocol.

I'd really appreciate it if you could help me find a way to create a button style that can achieve both of these desired effects. Thanks in advance.

struct TouchDownButtonStyle: PrimitiveButtonStyle {

    func makeBody(configuration: Self.Configuration) -> some View {
        MyButton(configuration: configuration)

    struct MyButton: View {
        @GestureState private var pressed = false

        let configuration: PrimitiveButtonStyle.Configuration

        var body: some View {
            let longPress = LongPressGesture(minimumDuration: 1.0, maximumDistance: 0.0)
                .updating($pressed) { value, state, _ in state = value }
                .onChanged{_ in self.configuration.trigger()} 

            return configuration.label
                .frame(width: 55, height: 200, alignment: .center)
                .background(RoundedRectangle(cornerRadius: 5).fill(Color.gray))
                .padding(.bottom, 50)
                .padding(.top, 50)
                .shadow(color: .black, radius: 3, y: 1)
                .opacity(pressed ? 0.5 : 1.0)
                .scaleEffect(pressed ? 0.95 : 1.0)
Terms of Service

Privacy Policy

Cookie Policy