Home > Mobile >  How can I animate individual rows in SwiftUI List?
How can I animate individual rows in SwiftUI List?

Time:09-22

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