Home > Back-end >  iOS 15 Swift UI VStack Animation doesn't push down rows as part of animating
iOS 15 Swift UI VStack Animation doesn't push down rows as part of animating

Time:11-16

I am just getting started with Swift UI today and followed a tutorial to have expanding sections. Everything went well and animated well until a deprecated warning came up for .animation(.default). I used the recommended method which converted to .animation(.default, value: isOpen) which also works, but the VStack does not animate the rows and looks terrible. Is there something I can do to remedy this?

Example with just .animation(.default)

enter image description here

Example with adjustment to .animation(.default, value: isOpen)

enter image description here

import SwiftUI

struct FilterTest: View {
    var body: some View {
        ScrollView{
            HeaderCellTest()
            HeaderCellTest()
            HeaderCellTest()
            HeaderCellTest()
            
            Spacer()
        }
    }
}

struct HeaderCellTest: View {
    @State private var isOpen: Bool = false
    
    var body: some View {
        content
            .padding(.leading)
            .frame(maxWidth: .infinity)
    }
    
    private var content: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("HEADING")
            }
            .onTapGesture { isOpen.toggle() }
            if isOpen {
                Group {
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                }
                .padding(.leading)
                
            }
            Divider()
        }
        .animation(.default, value: isOpen)
    }
}


struct FilterTest_Previews: PreviewProvider {
    static var previews: some View {
        FilterTest()
    }
}

CodePudding user response:

You should use VStack and delete Group!

struct FilterTest: View {
    var body: some View {
        ScrollView{
            HeaderCellTest()
            HeaderCellTest()
            HeaderCellTest()
            HeaderCellTest()
            
            Spacer()
        }
    }
}

struct HeaderCellTest: View {
    @State private var isOpen: Bool = false
    
    var body: some View {
        content
            .padding(.leading)
            .frame(maxWidth: .infinity)
    }
    
    private var content: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("HEADING")
            }
            .onTapGesture { isOpen.toggle() }
            if isOpen {
                VStack {                 // <<: Here!
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                }
                .padding(.leading)
                
            }
            Divider()
        }
        .animation(.default, value: isOpen)
    }
}

CodePudding user response:

When you want to animate a change you need to surround et modify value with a withAnimation block.

CF documentation: https://developer.apple.com/documentation/swiftui/withanimation(::)

Edited code :

private var content: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("HEADING")
            }
            .onTapGesture {
                // <--- Add block for animation --->
                withAnimation {
                    isOpen.toggle()
                }
            }
            if isOpen {
                Group {
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                }
                .padding(.leading)

            }
            Divider()
        }
        .animation(.default, value: isOpen)
    }
  • Related