1

I would like to have a button, which when pressed, changes to 'confirm'. On the second press, it executes the action. Simple enough so far.

I would also like that whenever the 'confirm' version of the button is showing, any interaction with any other view would reset the button to its original state. That could be touching the background, pressing another button, going to another tab, etc.

Very simple example of what I want to achieve.

My attempt is something like:

struct ContentView: View {
    @State private var confirmShowing = false

    var body: some View {
        ZStack {
            // Tappable background just to remove the confirmation
            Color(.systemBackground)
                .edgesIgnoringSafeArea(.all)
                .onTapGesture {
                    withAnimation {
                        confirmShowing = false
                    }
                }

            VStack {
                // Button which needs confirmation
                Button(action: {
                    if confirmShowing {
                        print("Executing")
                    }
                    withAnimation {
                        confirmShowing.toggle()
                    }
                }) {
                    Text( confirmShowing ? "Confirm" : "Do something" )
                }
                .padding()
                .background( Rectangle().foregroundColor( Color(.secondarySystemBackground) ) )
                .padding()

                // Completely different button which also should first reset confirmation
                Button("Do something else") {
                    withAnimation {
                        confirmShowing = false
                    }
                    // do some other stuff
                }
                    .padding()
                    .background( Rectangle().foregroundColor( Color(.secondarySystemBackground) ) )
                    .padding()
            }
        }
    }
}

It works for this very simple example, but it's not scalable. If I have 50 views I would have to add something to each of them just to control this one button.

Is there a better way? I'm happy to use UIViewRepresentable/UIViewControllerRepresentable.

UIKit must have this functionality right? I see it all the time in other apps and iOS in general.

1 Answer 1

0

The best way I can think of is to use an enum to control the button's state. For example. Please forgive any syntax errors, I don't have XCode open at the moment.

@State var buttonState: ButtonState = .initial

Button(action: {
    switch buttonState {
          case .initial:
              buttonState = .second
          case .second:
               //Perform whatever action after second.
          default:
               buttonState = .initial
     }
}, label: {
    switch buttonState {
        case .initial:
              Text("Some Initial Action")
        case .second:
              Text("Some Second Action")
        default:
              Text("Default Action")
    }
})

Then once you have that, create an enum to handle it.

enum ButtonState {
    case initial, second
}

Further usage is to simply add buttonState = .initial to whatever other button you want to trigger it to go back to default.

Sign up to request clarification or add additional context in comments.

2 Comments

My main issue with this approach is I would have to add that line to potentially many buttons and other views. In an ideal world I would love something like a onOtherViewTouched modifier that I could reset the state with.
Have a look at this solution for the "Global Tap Gesture" - stackoverflow.com/questions/62400806/… I think this should be exactly what you're looking for. Be warned, this is going to cause problems ultimately. The button itself will also trigger that global gesture, so you need to make sure you handle that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.