In an UIKit app I've built I used to have this effect where a scroll view would control the animation of enabling/disabling specific constraints in a view by using an UIPropertyAnimator and manipulating it's fractionComplete property. This allowed the animation to follow the scroll view's progression.
In SwiftUI I do not control constraints anymore but rather I change the whole view hierarchy based on a @State variable (for eg, the view I want to transition between 2 states has a property called isExpanded).
This simple transition is easily done with SwiftUI's withAnimation by simply toggling the bool value that I need. Using the matchedGeometryEffect(id:in:properties:anchor:isSource:) I can easily have elements move from/to the correct positions.
What I am trying to figure out is how can I basically pause and then control the progression of the animation so that the transition between my start and end state is controlled via a pan gesture or, like I used to do it in UIKit, via a ScrollView.
Here's a basic example of my SwiftUI code:
struct MyTwoStatesView: View {
@Namespace var namespace
@State var isExpanded: Bool = true
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 4)
.fill(Color.gray)
if isExpanded {
ExpandedStateView(namespace: namespace)
}
else {
CollapsedStateView(namespace: namespace)
}
}
.fixedSize(horizontal: false, vertical: true)
.onTapGesture {
withAnimation {
isExpanded.toggle()
}
}
}
}
And here's the effect that the final animation has:

Later edit: Here's a gist for the "full" example: https://gist.github.com/zeusent/39f58827519d9bfda63271a9cb24d6b6