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)
}
}
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) {
...
}
}