I've created this expanding view and it has child views in it that animated in an unexpected way.
In the animation below...
In the "Atlas" section...
The names and image circles stay in place as the parent collapses. The title text moves down but the names and avatars fade in while remaining in place. (The names and Title text move relative to each other)
In the "Luna" section...
The names and avatars are hidden by the view collapsing. (The names and Title text are always in the same relative place)
Ideally I'd like them to to act like the "Luna" section for all views.
My view body is like this at the moment...
VStack(alignment: .leading, spacing: 16) {
HStack {
VStack(alignment: .leading, spacing: 8) {
(
Text(session.startDate, style: .time)
+ Text(" - ")
+ Text(session.endDate, style: .time)
)
.font(.caption1)
Text(session.title)
.font(.headline6)
}
Spacer()
if session.canExpand {
if expanded {
Image(systemName: "chevron.up")
} else {
Image(systemName: "chevron.down")
}
}
}
if expanded {
ForEach(session.speakers) { speaker in
HStack {
Avatar(name: speaker.name, size: 24, imagePath: speaker.image)
Text("Test name \(Int.random(in: 1...30))")
.font(.body1)
}
}
}
}
I've tried changing the transition of the Avatar and name section but that didn't seem to have an effect.
The best way that I'm aware of to fix this problem is to get rid of
if expanded
and unconditionally include the speaker rows, but put the speaker rows in a container with a frame height of 0 when the session is collapsed. Add a clipping modifier to the outer session view (the view that draws the rounded rect and shadow) to hide the speaker rows when the card is collapsed. Here's the result:Here's my
SessionView
code:These are the main things to note in my code:
I unconditionally include the speaker rows.
I wrap the speaker rows in their own
VStack
. ThatVStack
has aframe
modifier with height zero if the session is not expanded.I apply a
clipShape
modifier to the outerVStack
so that the speaker rows are clipped when the session is collapsed.Here's the rest of the code, for experimentation: