Home > Net >  How to add a modifier to any specific buttons inside a ForEach loop for an array of buttons in Swift
How to add a modifier to any specific buttons inside a ForEach loop for an array of buttons in Swift

Time:11-29

How can I add modifiers according to my needs to individual buttons?

I have a ForEach loop running in a range of 0..<5 & I need to add an animation of .rotation3DEffect in clicked button and another .opacity on remaining un-clicked buttons, according to their state.

Note: I can watch for any state value inside buttons action, and then change it to have the animation, but since the modifier is applied on the Button itself inside the ForEach loop, I am having the animation applied to every buttons inside the foreach.

@State private var rotationDegree = 0.0
@State private var selectedNum = 0
@State private var correctAnswer = 0 // comes from saved data

var body: some View {
    
    ForEach(0..<5) { num in // image as a button, loops through their prefix name
        
        Button {
            selectedNum = (num == correctAnswer) ? num : 0
            withAnimation {
                // once clicked, will animate all 5 buttons, need only this clicked button to animate.
                if (num == correctAnswer) {
                    rotationDegree  = 360
                }
            }
            
        } label: {
            
            Image("imageName\(num)")
            
        }
        .rotation3DEffect((.degrees((selectedNum == correctAnswer) ? rotationDegree : 0.0)), axis: (x: 0, y: (selectedNum == correctAnswer) ? 1 : 0, z: 0)) // animation I want to add to a specific button
    }
}

CodePudding user response:

Try adding this to your view.

@State var selectedNum: Int = 0

Then change your button to look something like this.

Button {
  selectedNum = num

  withAnimation {
    rotationDegree  = 360
  }
} label: {
        Image("imageName\(num)")
    }
    // Check if the selected button is equal to the num
    .rotation3DEffect((.degrees(selectedNum == num ? rotationDegree : 0.0)), axis: (x: 0, y: 1, z: 0))

Not sure how the rotation3DEffect works. But here is another example

.background(selectedNum == num ? .red : .blue)

CodePudding user response:

import SwiftUI

struct AnimatedListView: View {
    var body: some View {
        VStack{
            ForEach(0..<5) { num in
                //The content of the ForEach goes into its own View
                AnimatedButtonView(num: num)
            }
        }
    }
}
struct AnimatedButtonView: View {
    //This creates an @State for each element of the ForEach
    @State private var rotationDegree = 0.0
    //Pass the loops data as a parameter
    let num: Int
    var body: some View {
            Button {
                withAnimation {
                    rotationDegree  = 360
                }
            } label: {
                Image(systemName: "person")
                Text(num.description)
            }
            .rotation3DEffect((.degrees(rotationDegree)), axis: (x: 0, y: 1, z: 0))
    }
}
struct AnimatedListView_Previews: PreviewProvider {
    static var previews: some View {
        AnimatedListView()
    }
}
  • Related