0

I want to implement the animation like AppStore. Drag down detail page to scale down and remove itself view. But when I started to drag, the console keeps printing var scale is changing and app is freezes. Looks like go into infinity loop. Here is my code:

import SwiftUI

struct TestView: View {
    @State var showDetail = false

    var body: some View {
        ZStack {
            Text("First View")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(Color.accentColor)
                .onTapGesture {
                    withAnimation {
                        showDetail = true
                    }
                }

            if showDetail {
                TestDetailView(showDetail: $showDetail)
            }
        }
        .ignoresSafeArea()
    }
}

struct TestDetailView: View {
    @State var scale: CGFloat = 1 {
        didSet {
            print("scale: \(scale)")
        }
    }

    @Binding var showDetail: Bool

    var body: some View {
        ScrollView {
            VStack(spacing: 0) {
                Text("Upper Part")
                    .foregroundColor(.white)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(Color.gray)
                    .gesture(DragGesture(minimumDistance: 0)
                        .onChanged { val in
                            let s = val.translation.height / UIScreen.main.bounds.height
                            if s > 0 && 1 - s > 0.7 {
                                scale = 1 - s
                                if scale < 0.8 {
                                    withAnimation {
                                        showDetail = false
                                    }
                                }
                            }
                        }
                    )

                Text("Lower Part")
                    .foregroundColor(.white)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(.primary)
                    .onTapGesture {
                        withAnimation(.easeInOut) {
                            showDetail = false
                        }
                    }
            }
            .frame(height: UIScreen.main.bounds.height)
        }
        .scaleEffect(scale)
        .animation(.easeInOut, value: showDetail)
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

I know it's relative to the drag gesture and setting scale but I don't know how to fix that.

enter image description here

enter image description here

enter image description here

The images above is what I want to implement, my code simplified the layout, you may try to drag down the upper part, then you'll know what happen.

miclendor
  • 65
  • 1
  • 9

0 Answers0