1

I am using a List in my app with some rows containing VStacks. I'm using a list and not a LazyVStack inside a ScrollView because I want to leverage some of the List features such as moving rows, swipe, etc.

When I try to add elements to a VStack in a list row with animation I get some jerky behavior and wondering if anyway to avoid this. My example to replicate this behavior is below:

struct ListAnimation: View {
    
    @State var showSecondText = false
    
    var body: some View {
        //ScrollView {
            List {
                VStack(alignment: .center) {
                    Text("First Text Title")
                    if showSecondText {
                        Text("Second Text Title")
                    }
                }
                .frame(maxWidth: .infinity)
                Button {
                    withAnimation {
                        showSecondText.toggle()
                    }
                } label: {
                    Text("Show Second Text")
                }
            }
        //}
    }
}

Uncommenting ScrollView and changing List to LazyVStack will make the animation very smooth. But in the List case, the animation is jerky and the First Text Title jumps up and down during the animation instead of staying in place. With larger more complex data the jerky animations are much more noticeable.

Is there anyway to avoid this when adding elements to a VStack in list row?

3
  • It looks like a bug where a change in the height of a List isn't animated. I suggest that you see if you can reproduce it in ios17 beta and then submit a feedback ticket. It may get fixed. Commented Jun 7, 2023 at 3:51
  • I'll try iOS 17 Beta and see if it persists. If so I'll follow your suggestion and submit a feedback ticket. Thx. Commented Jun 7, 2023 at 5:39
  • iOS 17 simulator has the same "jump" in height. Commented Jun 8, 2023 at 5:54

2 Answers 2

2

Apply the .animation() modifier to VStack and also update the flag with block of Animation. Use below code to achieve your expected output.

   List {
        VStack(alignment: .center) {
            Text("First Text Title")
            if showSecondText {
                Text("Second Text Title")
            }
        }
        .animation(.linear(duration: 0.5)) //Here apple animation modifier to VStack
        .frame(maxWidth: .infinity)

        Button {
            withAnimation(.linear(duration: 0.5)) { //Update the flag with animation also
                showSecondText.toggle()
            }
        } label: {
            Text("Show Second Text")
        }
    }
Sign up to request clarification or add additional context in comments.

Comments

0

You are not adding to the list, but adding to the VStack, hence the unexplained behaviour. The list sees the VStack as a single row.

You can add multiple items to the List directly.

List {
    Text("First Text Title")
    if showSecondText {
        Text("Second Text Title")
    }
    Button {
        withAnimation {
            showSecondText.toggle()
        }
    } label: {
        Text("Show Second Text")
    }

}

List has an implicit ScrollView (as does Form), so you don’t need to add one.

6 Comments

I may have worded the question incorrectly and I'll edit that. I want to add to the VStack in the list and avoid the messy animation.
Also, I'm not suggesting adding a ScrollView to a List. I'm saying if you change the List to A LazyVStack inside a ScrollView the behavior and animations are normal.
@alionthego Ah I see - sorry. Let me think.
I've tried .animation modifiers and it didn't work. The link you provided is interesting and indeed the same behavior but the solution from Asperi is assuming you know the beginning and end heights. in my case I don't know the heights of each element as items are added and the VStack grows in height.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.