Animation
What happens between two states
You never animate a view in SwiftUI. You change a value, and say that changes to that value should be interpolated rather than applied at once.
That sentence is the whole chapter, and it is why the API looks strange coming from UIKit. There is no “animate this view” call, because a view is a description that gets thrown away — there is nothing there to animate. What persists is the value, and the animation belongs to it.
withAnimation(.spring) {
isExpanded.toggle()
}
Nothing in that block mentions a view. It changes a Bool, and every view whose layout or
appearance depends on that Bool interpolates from where it was to where it now belongs.
Why this matters more than it sounds
In UIKit, an animation is a thing you start, and it has to be reconciled with whatever else is running: two animations on the same property fight, an interrupted animation snaps, and cancelling one halfway leaves the layer in a state nobody planned.
In SwiftUI the current state is always the truth. An animation is the route from the old truth to the new one, so interrupting it is not a special case — a new change simply starts a new route from wherever the value currently is. Springs make this look right without any effort on your part, which is why they are the default.
The two chapters
Implicit and explicit is about the two ways to attach an animation — .animation(_:value:) on
a view versus withAnimation around a change — when each is correct, and why the modifier grew a
value: parameter. It covers Animatable and how a custom value becomes interpolatable, which is
the piece that turns animation from a set of built-ins into something you can extend.
Transitions and matched geometry is about views arriving and leaving rather than changing:
.transition, why it needs an animation to run at all, and matchedGeometryEffect for the case
where a view should appear to move between two places in the tree rather than fade out in one and
in at the other.
One rule to carry in
Animation follows identity. A view that keeps its identity animates from its old state to its new one. A view that gets a new identity is a different view: the old one transitions out, the new one transitions in, and no property is interpolated between them.
Every “why did it jump instead of sliding?” is that distinction. Before reaching for a different easing curve, check whether the thing you expected to animate is even the same view it was a frame ago — the identity chapter is where that is decided.