我创建了一个插入三个按钮的简单函数。我想要一个单独的按钮在按下时旋转。我最初的尝试是这样的:
ForEach(0..<3, id: \.self) { number in {
Button(action: {
self.flagTapped(number: index)
withAnimation(Animation.interpolatingSpring(stiffness: 15.0, damping: 3.0)) {
animationAmount2 += 360
}
}) {
Image(self.countries[index])
.renderingMode(.original)
}
.clipShape(Capsule())
.overlay(Capsule().stroke(Color.black, lineWidth: 1)
.shadow(color: .black, radius: 10, x: 3, y: 3)
.rotation3DEffect(
.degrees(animationAmount2),
axis: (x: 0.0, y: 1.0, z: 0.0),
anchor: .center,
anchorZ: 0.0,
perspective: 1.0
)
}
它可以工作,但问题是当你按下任何按钮时每个按钮都会动画,因为 animationAmount2 是一个 @State 属性,所以当它更新时,每个按钮都会动画,而不仅仅是按下的那个。
我的下一个想法是创建一个自定义按钮并在其中插入动画代码和属性,以便按钮单独动画。结果是:
func getFlagView(index: Int) -> some View {
let flag = CustomButton(country: countries[index], index: index) { (Index) in
flagTapped(number: index)
}
return flag
}
我现在在 ForEach 中调用这个函数,它完美地插入了按钮,并且只有我按下的按钮会旋转。问题是当视图刷新时它永远不会重绘按钮。ForEach 正在执行,但它只是忽略了对 getFlagView 的调用。
在 CustomButton 调用的末尾添加 .id(UUID()) 修复了以下问题:
func getFlagView(index: Int) -> some View {
let flag = CustomButton(country: countries[index], index: index) { (Index) in
flagTapped(number: index)
}.id(UUID())
return flag
}
现在,当视图按预期刷新时,按钮会重绘,但动画不起作用。我真的不知道为什么添加 UUID 会破坏动画。