如何为 SwiftUI 中的按钮数组的 ForEach 循环内的任何特定按钮添加修饰符?

How to add a modifier to any specific buttons inside a ForEach loop for an array of buttons in SwiftUI?

如何根据需要给各个按钮添加修饰符?

我在 0..<5 的范围内有一个 ForEach 循环 运行 & 我需要在单击的按钮中添加一个 .rotation3DEffect 的动画和另一个 .opacity 在剩余的未点击按钮上,根据它们的状态。

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
    }
}

尝试将其添加到您的视图中。

@State var selectedNum: Int = 0

然后将您的按钮更改为如下所示。

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))

不确定 rotation3DEffect 的工作原理。但这是另一个例子

.background(selectedNum == num ? .red : .blue)
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()
    }
}