In SwiftUI, I am working with two screens, Display screen A and Display screen B. I am trying to create a transition impact utilizing SwiftUI’s matched geometry function. The transition includes two rounded rectangles: one on Display screen A, which seems as a circle as a result of its nook radius and dimension, and one other on Display screen B with a zero nook radius, serving because the background.
Anticipated Habits:
I anticipated the animation would show as a seamless morphing of a single object from one configuration to a different, particularly altering the nook radius, peak, and width.
Precise Habits:
Nevertheless, whereas at first look that’s what seems to occur, in case you look nearer, you see the transition appears to be extra of a crossfade. Because it fades out, the supply form does interpolate its nook radius in the direction of the goal configuration, however the goal form, because it fades in doesn’t interpolate from the supply radius.
This screenshot of the highest proper part of the animation at approx 50% elapsed illustrates the undesired habits:
Its appears unlikely the cross fade can merely be “turned off” … I suppose a cross fade could also be important to matchedGeometry impact, because it appears it could be the one technique to interpolate between sure properties like a distinct fill… however even when that is true, it would not be obvious if solely the goal form was additionally interpolating its form… which it isn’t on this case.
I would really like any reply not to alter the animation mechanism — that is only a simplified model of a bigger undertaking. The animation have to be triggered by withAnimation{} and act upon the navController.display.
Minimal Instance Code:
Fundamental Display screen:
enum Display screen {
case foremost, goal
}
@Observable
class Nav {
var display:Display screen = .foremost
}
struct ContentView: View {
@Atmosphere(Nav.self) var navController
// matched geometry
@Namespace var namespace
var physique: some View {
swap navController.display {
case .foremost:
ZStack{
RoundedRectangle(cornerRadius: 15)
.fill(Coloration.inexperienced)
.matchedGeometryEffect(id: "circleToBackground", in: namespace)
.body(width: 30, peak: 30)
.onTapGesture {
withAnimation(.easeInOut(period: 4.0)){
navController.display = .goal
}
}
}
case .goal:
TargetScreen(namespace: namespace)
}
}
}
Goal Display screen:
struct TargetScreen: View {
let namespace: Namespace.ID
@Atmosphere(Nav.self) var navController
var physique: some View {
ZStack {
RoundedRectangle(cornerRadius: 0)
.fill(LinearGradient(colours: [Color.green, Color.white], startPoint: UnitPoint(x:0.5,y:0.0), endPoint: UnitPoint(x:0.5,y:1.0)))
.matchedGeometryEffect(id: "circleToBackground", in: namespace)
.body(maxWidth: .infinity, maxHeight: .infinity)
Textual content("BACK").onTapGesture {
withAnimation {
navController.display = .foremost
}
}
}
}
}