Issue #853

With ButtonStyle, the disabled modifier does not seem to work, we need to use allowsHitTesting.

import SwiftUI

struct ActionButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            Text("Button")
        }
        .padding()
        .disabled(true) // does not work
        .allowsHitTesting(false)
    }
}

We need to call disabled outside, after buttonStyle. In case we have onTapGesture on the entire view, touching on that disabled button will also trigger our whole view action, which is not what we want.

VStack {
    Button(action: onSave) {
        Text("Save")
    }
    .buttonStyle(ActionButtonStyle())
    .disabled(true)
}
.onTapGesture {
    window.endEditing(true)
}

Another way is to overlay with a dummy view with a dummy tap gesture to obscure the action

extension View {
    func disableInteraction(_ shouldDisable: Bool) -> some View {
        disabled(shouldDisable)
            .overlay(
                Group {
                    if shouldDisable {
                        DummyView()
                            .onTapGesture {}
                    }
                }
            )
    }
}

private struct DummyView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {}
}

So that we have

Button(action: onSave) {
    Text("Save")
}
.buttonStyle(ActionButtonStyle())
.disableInteraction(true)