I am trying to create a transition between two views. As I am currently just testing the transition, both views are very simple.
The first view called "Playground5" contains a small rectangle, which I would like to transition into the second view "Playground 6" which contains a full screen rectangle of the same colour.
I would like the transition to "expand" outwards and "inwards".
The transition between the two views works, but it looks a bit weird.
When the rectangle expands, it reaches the top and bottom before the sides, instead of the same time.see img.
Any ideas on how to solve this?
import SwiftUI
struct Playground5: View {
@State private var expandRectangle = false
@Namespace private var namespace
var body: some View {
VStack {
if expandRectangle {
Playground6(expandRectangle: $expandRectangle, namespace: namespace)
// .matchedGeometryEffect(id: "rectangle", in: namespace)
} else {
Rectangle()
.foregroundColor(Color.red)
.frame(width: 200, height: 400)
// .frame(width: expandRectangle ? 400 : 200, height: expandRectangle ? 600 : 400)
.onTapGesture {
withAnimation {
expandRectangle.toggle()
}
}
.matchedGeometryEffect(id: "rectangle", in: namespace, properties: .position, anchor: .center)
}
}
.ignoresSafeArea(.all)
}
}
struct Playground6: View {
@Binding var expandRectangle: Bool
var namespace: Namespace.ID
@Namespace private var namespace2
var body: some View {
// ZStack {
Rectangle()
.onTapGesture {
withAnimation {
expandRectangle.toggle()
}
}
.foregroundColor(Color.red)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea(.all)
.matchedGeometryEffect(id: "rectangle",in: namespace)
}
}
ignoresSafeArea
should be set on the container of the entire thing, rather than on each individual component, otherwise (I think) the namespace isn't taking the safe area into account. If I remove the ignoresSafeArea
modifier from Playground5
and Playground6
and make the preview like this:
static var previews: some View {
Playground5()
.ignoresSafeArea(.all)
}
The view scales normally.
The problem was much easier to see when slowing down the animation, you can see it hits the edges of the safe area and then jumps to fill the rest:
withAnimation(.easeInOut(duration: 5)) {
expandRectangle.toggle()
}