I have a view based on a few state variables. These states are set by the completion block of an API call. The bookings
are displayed as a ForEach
list and I want them to appear with the slide
transition.
The slide
transition worked perfectly. Since I added the !isLoading
check, these animations no longer display. All the animations that appear now are the fade in/out of the ProgressView
. When removing the !isLoading
check, the staggered slide animation comes back, but I want to keep this check so I can properly handle loading states.
Here is a standalone code to reproduce the issue:
import SwiftUI
struct RoomView: View {
@State private var room: String?
@State private var bookings: [String]?
@State private var isLoading: Bool = false
var body: some View {
VStack(spacing: 0) {
if /* This is the problematic condition !isLoading, */ let room = self.room {
ScrollView {
LazyVStack(alignment: .leading) {
Text(room)
if let bookings = bookings {
ForEach(bookings.indices) { (index) in
let booking = bookings[index]
VStack(alignment: .leading) {
Text(booking)
Divider()
}
.transition(.slide)
// Stagger the animations when displaying the list
.animation(Animation.spring().delay(0.04 * Double(index)))
}
}
}
.padding()
}
} else {
// If we're loading
ProgressView("Loading Room")
}
}
.transition(.opacity)
.animation(.easeInOut)
.onAppear {
self.isLoading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.room = "Demo room"
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
withAnimation {
self.bookings = ["Booking 1", "Booking 2", "Booking 3", "Booking 4", "Booking 5"]
self.isLoading = false
}
}
}
}
}
}
struct RoomView_Previews: PreviewProvider {
static var previews: some View {
RoomView()
}
}
Is there a known issue with SwiftUI animations where having multiple conditions could cause transitions to not appear? How can I fix this so I keep my staggered animation & fade of the ProgressView
transitions without removing the !isLoading
check?
Here is possible solution - make views independent. Tested with Xcode 12 / iOS 14.