使用ForEach插入的SwiftUI视图不使用动画更新


我创建了一个插入三个按钮的简单函数。我想要一个单独的按钮在按下时旋转。我最初的尝试是:
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会破坏动画。

为了让SwiftUI为按钮设置动画,它需要能够观察到唯一标识视图的渲染之间的变化。在第一种情况下,您的视图具有id的012。所以动画成功了。

当您应用.id(UUID())时,这会在每次绘制按钮时为其提供一个唯一的id。因此,SwiftUI不会看到您更改了一个按钮,因为每次执行ForEach时,它总是将这3个按钮视为3个全新的按钮。

您需要的是一个id,它可以唯一地识别每个按钮,但在国家/地区发生变化之前,它不会发生变化。您需要一个唯一标识每个国家的id,并且id是国家的名称。

更改您的getFlagView以使用国家名称作为id:

func getFlagView(index: Int) -> some View {

let flag = CustomButton(country: countries[index], index: index) { (Index) in
flagTapped(number: index)
}.id(countries[index])

return flag
}

相关内容

  • 没有找到相关文章

最新更新