Home > Enterprise >  Group buttons and change icon color on active selection
Group buttons and change icon color on active selection

Time:10-24

So I have a few buttons inside a VStack() which I want to bind or combine with one state property, to determine when each button was clicked.

When a button is clicked, I want to use the .accentColor modifier while the action is active and when the action is done, fallback to the original Color.secondary.

Currently, here is what it's doing:

- When app is opened, it loads the default color.
- When one button is clicked, it turns both buttons into a lighter shade of gray.
- When I exit the view, it turns both buttons to accentColor and keeps them like that.
- When I click on a button again, it turns gray.

Video for reference:
https://im5.ezgif.com/tmp/ezgif-5-d53f89a9af.gif

Could anyone spot what I might be doing wrong?

So I have the following code (Code has been stripped of all the unnecessary items, such as var body: some View, etc..):

@State private var tappedActiveMapAnnotationButton : Bool = false

VStack {
    Button(action: {
        withAnimation(.spring()) {
            self.tappedActiveMapAnnotationButton = true
            mainViewModel.showFilters.toggle()
        }
    }, label: {
        Image(systemName: "slider.horizontal.3")
            .font(.title3)
            .padding(10)
            .foregroundColor(tappedActiveMapAnnotationButton ? .accentColor : Color.secondary)
    }) //: Button
    Button(action: {
        withAnimation(.spring()) {
            self.tappedActiveMapAnnotationButton = true
            showMapDisplaySheet.toggle()
        }
    }, label: {
        Image(systemName: "map")
            .font(.title3)
            .padding(10)
            .foregroundColor(tappedActiveMapAnnotationButton ? .accentColor : Color.secondary)
    }) //: Button
    .sheet(isPresented: $showMapDisplaySheet) {
        MapDisplaySheetView()
            .presentationDetents([.fraction(0.25)])
    }
} //: VStack
.background {
    RoundedRectangle(cornerRadius: 8)
        .fill(Color(uiColor: .systemBackground))
}

CodePudding user response:

Create the following enum

enum buttonSelection {
    case buttonNone, button1, button2
}

and you essentially create a single state variable of the type buttonSelection and perform whatever you want based on the current value of buttonSelection

        @State private var currentSelection : buttonSelection = .buttonNone

        VStack {
            Button(action: {
                withAnimation(.spring()) {
                    self.currentSelection = .button1
                    mainViewModel.showFilters.toggle()
                }
            }, label: {
                Image(systemName: "slider.horizontal.3")
                    .font(.title3)
                    .padding(10)
                    .foregroundColor(currentSelection == .button1 ? .accentColor : Color.secondary)
            }) //: Button
            Button(action: {
                withAnimation(.spring()) {
                    self.currentSelection = .button2
                    showMapDisplaySheet.toggle()
                }
            }, label: {
                Image(systemName: "map")
                    .font(.title3)
                    .padding(10)
                    .foregroundColor(currentSelection == .button2 ? .accentColor : Color.secondary)
            }) //: Button
            .sheet(isPresented: $showMapDisplaySheet, onDismiss: {
                print("Dismissed")
                currentSelection = .buttonNone
            }) {
                MapDisplaySheetView()
                .presentationDetents([.fraction(0.25)])
            }
        } //: VStack
        .background {
            RoundedRectangle(cornerRadius: 8)
                .fill(Color(uiColor: .systemBackground))
        }

  • Related