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.
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.