I want to show a List, where each row appears with an opacity animation and with an increasing delay. So 1st row should appear after 0.1 seconds, second after 0.3 seconds, third after 0.5 seconds etc.
I tried the following, but it does not work, as all rows appear at once and without animation.
Any tips would be much appreciated!
struct GuideListView: View {
@State var showListItems = false
@State var animationDelay = 0.1
// definitions of viewRouter, data etc.
var body: some View {
VStack {
// other items, navLink etc.
List {
ForEach(data) { item in
Button(action: {
// navigation action
}, label: {
RowView(item: item)
})
.opacity(showListItems ? 1 : 0)
.animation(Animation.easeOut(duration: 0.6).delay(animationDelay), value: showListItems)
.onAppear{
animationDelay = animationDelay 0.2
}
} //: ForEach
} //: List
} //: VStack
.onAppear{
showListItems = true
}
}
CodePudding user response:
The key seems to be using the indices from the ForEach loop to set the times at which the animations appear. Also, please ask questions with a minimal, reproducible example so we don't have to recreate things to help you.
Below is the code. The toggle switch just resets the state to show the animation:
struct GuideListView: View {
let data = ["One", "Two", "Three", "Four"]
@State var showListItems = false
@State var animationDelay = 0.5
// definitions of viewRouter, data etc.
var body: some View {
VStack {
// other items, navLink etc.
Toggle("Show List Items", isOn: $showListItems)
List {
ForEach(data.indices) { index in
Button(action: {
// navigation action
}, label: {
Text(data[index])
})
.opacity(showListItems ? 1 : 0)
.animation(Animation.easeOut(duration: 0.6).delay(animationDelay * Double(index)), value: showListItems)
} //: ForEach
} //: List
} //: VStack
}
}