You’ve got a lot going on here! The solution is to clean it up a bit.
I’ve put your original code and my solution on GitHub for you here. You’ll want to adjust it a bit because I didn’t center the detailed view on the screen like you did, but everything else works.
First, you shouldn’t define new views as variables or functions. Make a whole new struct that conforms to View and has its own body instead, and pass in any values needed from the parent. This is going to allow SwiftUI to keep track of everything better, and it will automatically redraw all subviews if any state changes in the parent view.
Once you’ve done that, you want to put the .matchedGeometryEffect
modifier in two spots that you know are going to be for the same view. In your original code, you only have it once on the personView
, which is sometimes rendered inside of a detailView
and sometimes not. Just bring it down to one spot where the personView is small and another where it’s large.
As you can see in the screenshot and in the repo I’ve attached, I’ve used it once inside the conditional and again inside the overlay’s conditional. Both of them are directly on PersonView
.
You’ve made a really cool effect! Just keep working with SwiftUI and try to learn “the Apple way” to think about how views are composed, and… well, you’ll still run into these problems lol. But hopefully they’ll be a little easier to diagnose.
ETA: I took out the .transition
as well, but that’s not reflected in the screenshot. Whoops. It removes the “jump” from 300 to 100 height at the end of the animation.