Hi everyone! I've recently started using this pager (2.5.0) on a production app and I've been facing a recycling issue I’ve not been able to solve.
Each page has 1 post, that fills the whole screen. The first batch of posts is fetched and displayed with no issues. After that, I dynamically add new posts at the top of the list; 1 post at a time. That’s when the issue arises! It seems that the new post view copies the state of the next and shows a subview that shouldn’t show.
Here's the pager:
Pager(page: viewModel.feedPage,
data: viewModel.feedItems,
id: \.self,
content: { index in
if index < viewModel.posts.count {
PostView(post: viewModel.posts[index])
} else {
Text("Loading...")
.foregroundColor(.white)
.font(.default(size: 17))
}
})
.vertical()
.sensitivity(.custom(0.1))
.onPageWillChange { index in
viewModel.willChangeVerticalPage(index: index)
}
struct PostView: View {
@StateObject private var viewModel = ViewModel()
let post: Post
var body: some View {
VStack {
SendFriendRequestView(userId: post.user.id) // the subview inside UserViews is the issue
PostImageView(imageURL: post.imageURL, text: post.text)
}
.onAppear {
viewModel.setUp(post: post)
}
.environmentObject(viewModel)
}
}
fileprivate struct SendFriendRequestView: View {
@EnvironmentObject private var viewModel: PostView.ViewModel
let userId: String
var body: some View {
Button {
viewModel.sendFriendRequest(userId: userId)
} label: {
HStack {
switch viewModel.sendFriendRequestViewState {
case .send: sendView
case .loading: loadingView
case .waiting: waitingView
case .hidden: EmptyView()
}
}
}
.disabled(viewModel.sendFriendRequestViewState != .send)
}
var sendView: some View {
HStack {
Image(systemName: "person.2.fill")
.resizable()
.scaledToFit()
.foregroundColor(.white)
.frame(width: 10, height: 10)
Text("Add+")
.foregroundColor(.white)
.font(.default(size: 13))
}
.padding(8)
.background(
Capsule().fill(.white.opacity(0.2))
)
}
var loadingView: some View {
ProgressView()
.tint(.white)
.padding(8)
.background(
Capsule().fill(.white.opacity(0.2))
)
}
var waitingView: some View {
HStack {
Text("Sent")
.foregroundColor(.white)
.font(.default(size: 13))
Image(systemName: "checkmark")
.resizable()
.scaledToFit()
.foregroundColor(.white)
.frame(width: 10, height: 10)
}
.padding(8)
.background(
Capsule().fill(.white.opacity(0.2))
)
}
}
And here are the involved pieces of the view model:
Hi everyone! I've recently started using this pager (
2.5.0
) on a production app and I've been facing a recycling issue I’ve not been able to solve.Each page has 1 post, that fills the whole screen. The first batch of posts is fetched and displayed with no issues. After that, I dynamically add new posts at the top of the list; 1 post at a time. That’s when the issue arises! It seems that the new post view copies the state of the next and shows a subview that shouldn’t show.
Here's the pager:
And here are the involved pieces of the view model:
I realized that if I add
.contentLoadingPolicy(.lazy(recyclingRatio: 0))
fixes my issue, but I don’t think it’s a good practice. Any ideas?