When creating and using a custom ButtonStyle for a SwiftUI button that changes its appearance based on the value of the configuration.isPressed property, that property sometimes get stuck with a "true" value, leaving the button to appear in its pressed state even when it is not being pressed. It stays stuck this way until the button is clicked again.
A sample project is attached. It's also in a public repo at https://github.com/siracusa/SwiftUIButtonIsPressedStateBug
To reproduce the bug:
-
Build and launch the sample project. A window should appear showing a large button view with a green background and some white text that says "Hello".
-
Click button view a few times and confirm that background color turns blue on mouse-down and switches back to green on mouse-up.
-
Grab a text file from the Finder and drag it on top of the green window, but don't release the mouse button. The text "Hello" should turn red when the file is over the button, and the button background should remain green.
-
While still holding down the mouse button to continue the drag operation, drag the file into and out of the button window. You will need to do this many times, pausing while holding the file over the button for a moment or two every few attempts.
Expected results:
The button view background remains green during the entire drag operation, because at no point during the drag operation is the button "pressed."
Actual results:
Eventually, the button background will turn blue, and then it will stay blue until the button is clicked normally.
See video for a reproduction demonstration: https://twitter.com/siracusa/status/1458456061032140802
I couldn't reproduce the behaviour you're describing. In theory, if highlighted is set to true in dropEntered you should never see the blue background if you only set if when highlighted is false and isPressed is true.
.background(configuration.isPressed && highlighted == false ? Color.blue : Color.green)
That's the only way I can get around the fact that isPressed is set to true during a drag.
As you say, the mouse is down during the drag so you can't check that.
I don't think there is anything wrong in your code, it has to be some weird bug that sets the isPressed value at the wrong time.