SwiftUI: How to animate List when being populated

I want to display a simple message while waiting for a list to be populated. Something like Loading... and when the list starts being populated with even one item, remove the message, via a transition, and display the list.

My current attempt, that does not work, looks like:

struct JoinChannelView: View {

    @Binding var rooms: [ChannelInfo]

    @State var selectedRoom: String?

    var body: some View {

        VStack {

            if $rooms.isEmpty {

                Text("Loading...")

                    .transition(.slide)

            } else {

                List(selection: $selectedRoom) {

                    ForEach(rooms, id: \.title) { room in

                        Text(room.title)

                            .font(.title)

                        Text(room.description)

                            .font(.subheadline)

                    }

                    .padding(.bottom)

                }

            }

        }

        .frame(width: 150, height: 300)

    }

}
Answered by BabyJ in 728459022

It seems the problem lies with the if-else statement and the way SwiftUI handles view identity and layout.


First of all, you need to be animating changes to the rooms property otherwise there will be no animated transition.

Something like this can work, but there are other ways:

withAnimation {
    rooms.append(newRoom)
}



As the List will not be shown when it has no items, you can use a single if statement for the loading text, and the transition which will work as expected.

Here's how it would look:

ZStack {
    if items.isEmpty {
        Text("Loading...")
            .transition(.slide)
            .zIndex(1) // place above the List (with ZStack)
    }

    List(selection: $selectedRoom) {
        ...               
    }
}
Accepted Answer

It seems the problem lies with the if-else statement and the way SwiftUI handles view identity and layout.


First of all, you need to be animating changes to the rooms property otherwise there will be no animated transition.

Something like this can work, but there are other ways:

withAnimation {
    rooms.append(newRoom)
}



As the List will not be shown when it has no items, you can use a single if statement for the loading text, and the transition which will work as expected.

Here's how it would look:

ZStack {
    if items.isEmpty {
        Text("Loading...")
            .transition(.slide)
            .zIndex(1) // place above the List (with ZStack)
    }

    List(selection: $selectedRoom) {
        ...               
    }
}
SwiftUI: How to animate List when being populated
 
 
Q