Swiftui 选择器中的动画更改将多次运行动画
我有以下代码:Swiftui 选择器中的动画更改将多次运行动画,swiftui,Swiftui,我有以下代码: import SwiftUI let names = ["John", "Betty", "Fred", "May", "Judy"] struct ContentView: View { @State var selection = 0 var body: some View { VStack(spacing: 20) { Picker("Name", selection: self.$selection.anima
import SwiftUI
let names = ["John", "Betty", "Fred", "May", "Judy"]
struct ContentView: View {
@State var selection = 0
var body: some View {
VStack(spacing: 20) {
Picker("Name", selection: self.$selection.animation(.linear(duration: 0.3))) {
ForEach(names.indices, id: \.self) { i in
Text(names[i]).tag(i)
}
}.pickerStyle(SegmentedPickerStyle())
Text(names[self.selection])
.font(.title)
.fixedSize()
.modifier(MyShake(animatableData: CGFloat(self.selection)))
}
.padding()
}
}
struct MyShake: GeometryEffect {
var animatableData: CGFloat
func modifier(_ x: CGFloat) -> CGFloat {
10 * sin(x * .pi * 2)
}
func effectValue(size: CGSize) -> ProjectionTransform {
let transform1 = ProjectionTransform(CGAffineTransform(translationX: 10 + modifier(animatableData), y: 0))
return transform1
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewDevice("iPhone SE")
}
}
如果从John切换到Betty(即选择当前片段旁边的片段),动画将运行一次,这正是我想要的。但是,如果从John切换到Fred,动画将运行多次,因为选择实际上不会从0移动到2,而是在其间对每一步进行插值
如何限制动画只运行一次?正如我看到的,它需要将
选择
转换为切换
。请找出以下可能的方法。已测试并可与Xcode 11.2/iOS 13.2配合使用
演示:
更改仅在ContentView
中进行:
struct ContentView: View {
@State var selection = 0
@State var shaking = false
var body: some View {
let value = Binding<Int>(
get: { self.selection },
set: { newValue in
withAnimation(Animation.linear(duration: 0.3)) {
self.shaking.toggle()
}
self.selection = newValue
})
return VStack(spacing: 20) {
Picker("Name", selection: value) {
ForEach(names.indices, id: \.self) { i in
Text(names[i]).tag(i)
}
}.pickerStyle(SegmentedPickerStyle())
Text(names[self.selection])
.font(.title)
.fixedSize()
.modifier(MyShake(animatableData: CGFloat(self.shaking ? 1 : 0)))
}
.padding()
}
}
struct ContentView:View{
@状态变量选择=0
@状态变量=false
var body:一些观点{
让值=绑定(
获取:{self.selection},
集合:{newValue in
带动画(动画.线性(持续时间:0.3)){
self.shacking.toggle()
}
self.selection=newValue
})
返回VStack(间距:20){
选择器(“名称”,选择:值){
ForEach(names.index,id:\.self){i in
文本(名称[i])。标记(i)
}
}.pickerStyle(SegmentedPickerStyle())
文本(名称[自选择])
.font(.title)
.fixedSize()
.modifier(MyShake(animatableData:CGFloat(self.shacking?1:0)))
}
.padding()
}
}
有趣的解决方案。自定义绑定可以将更改扩展到两个状态变量。然后,动画由bool状态变量驱动,而不是int状态变量。聪明。