Home > Mobile >  Choppy Animation SwiftUI Nested Views
Choppy Animation SwiftUI Nested Views

Time:10-09

I'm working on an animation that brings up a view from the bottom of the screen above part of the view that previously occupied the screen. My code is technically working, though I'm concerned that the animation looks too choppy. Basically, what I think is happening is that the new, rising view is composed of several other views, and when I animate it coming up, it also animates the sub-views coming together--something I don't like the look of.

Sample Code:

struct ButtonView: View {
    @State var show: Bool = false
    var body: some View {
        ZStack{
            VStack {
                Button(action: { withAnimation(.linear(duration: 0.5)) { show = !show }} )  {
                    Text("Press Me")
                }
                Rectangle()
                    .foregroundColor(.gray)
            }
        }
        if show {
            VStack {
                CollapsibleView()
            }
        }
    }
}

struct CollapsibleView: View {
    var body: some View {
        ZStack {
            VStack {
                Text("Text 1")
                Text("Text 2")
                Text("Text 3")
            }
            .background(Color.white)
        }
    }
}

Note that the duration is set to be quite long for illustration purposes, but even at smaller duration values I can still notice the choppy effect.

How do I avoid this? Is there a way to just animate the motion?

CodePudding user response:

Here a way for what you may looking for:

struct ContentView: View {
    
    @State var show: Bool = Bool()
    
    var body: some View {
        
        VStack {
            
            Button(action: { show.toggle() }, label: { show ? Text("hide") : Text("show") })
                .animation(nil)
            
            Color.gray
            
            Group {
                
                if show { CollapsibleView().transition(.asymmetric(insertion: .move(edge: .bottom), removal: .move(edge: .bottom))) }
                
            }
            .opacity(show ? 1.0 : 0.0)
            
        }
        .animation(Animation.spring(response: 0.4, dampingFraction: 0.4, blendDuration: 1.0), value: show)
        
        
    }
}

struct CollapsibleView: View {
    var body: some View {
        
        VStack(alignment: .leading) {
            Text("Text 1")
            Text("Text 2")
            Text("Text 3")
        }
        .background(Color.white)
        
    }
}
  • Related