I have implemented a LazyVGrid to display movie posters, and I am trying to find a mechanism to load additional items using an asynchronous function. I have positioned a ProgressView at the end of the ForEach, which triggers an onAppear event. However, I am encountering a strange behavior where, at times, the onAppear does not get triggered. This is not related to my function, as I also use a print statement that isn’t triggered either.
Here’s a video demonstrating the issue along with my code:
LazyVGrid(columns: [GridItem(.adaptive(minimum: 150))], spacing: 15) {
ForEach(filmObserver.movies, id: .id) { movie in
NavigationLink(destination: ItemDetailView(type: itemType.Film, itemId: movie.id)){
ItemCardView(movieData: movie)
}
}
if filmObserver.hasNext && !filmObserver.movies.isEmpty {
ProgressView()
.frame(width: 150, height: 200, alignment: .center)
.onAppear {
print("refresh!!!")
filmObserver.fetchItem(type: itemType.Film)
}
}
}
Any insights on why onAppear might not be firing would be greatly appreciated. Thank you!
2
Answers
I tried to check if the last element of my forEach is reached, and now onAppear behaves as expected, but it's not very elegant. I'd rather prefer to use my ProgressView.
Use a geometry reader in a background to deterministically detect when ProgressView appears on the bottom of the screen. The onAppear modifier fires within the SwiftUI lifecycle and will not always fire when expected.
After your fetch operation completes and ProgressView has once again been pushed offscreen, you’ll want to reset hasFetched.