swiftuiswiftui-animationswiftui-zstackswiftui-vstack

VStack flashing of space between views


The VStack has two components header and detail. When we tap on the "show" button, it shows the View (header + detail of the VStack). However, it results in Flashing effect when the view Slides in.

After the animation is complete the View spacing looks fine. During the animation it shows spacing for a while before disappearing at the end of animation, how can this be fixed?


struct StackAnimation: View {
    @State var show: Bool
    var body: some View {
        ZStack {
            Button {
                show.toggle()
            } label: {
                Text("Show View")
            }
            
            ZStack{
                VStack{ // animation
                    if show {
                        VStack(spacing: 0) { // VStack with no spacing
                            VStack {
                                Text("Header")
                                
                            }
                            .frame(maxWidth: .infinity, maxHeight: 30.0)
                            .background(Color.white)
                            Text("Detail")
                                .frame(maxWidth: .infinity, maxHeight: .infinity)
                                .background(Color.white)
                        }.cornerRadius(10.0).padding(.top, 20)
                            .transition(.move(edge: .bottom))
                    }
                }.animation(.spring().delay(0.3), value: show)
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.green)
        
    }
}

struct StackAnimation_Previews: PreviewProvider {
    static var previews: some View {
        StackAnimation(show: false)
    }
}

enter image description here


Solution

  • You can use the following code within If condition.

                        VStack(spacing: 0) {
                              VStack {
                                  Text("Header")
                              }
                              .frame(maxHeight: 30.0)
                              Text("Detail")
                                  .frame(maxHeight: .infinity)
                          }
                          .frame(maxWidth: .infinity)
                          .background(Color.white)
                          .cornerRadius(10.0)
                          .padding(.top, 20)
                          .transition(.move(edge: .bottom))
    

    enter image description here