fermoya / SwiftUIPager

Native Pager in SwiftUI
MIT License
1.31k stars 172 forks source link

[BUG] Vertical pager breaks when adding content on the start of the list, on demand #298

Open Samigos opened 2 years ago

Samigos commented 2 years ago

Xcode version: 14.0 SwiftUIPager version: 2.5.0

I have an app, that shows posts on a vertical pager. Each page fills the whole screen.

So, when the app launches, I fetch the 10 most recent posts and display them. As soon as those posts are fetched, I start listening for new posts. (see code below) Whenever that callback gets triggered, a new post is created. I take it and place it on the top of my list.

The thing is when I scroll to find the new post, its views get mixed up with the views of the next post. Here's what I mean:

Before the new post, I have the one below https://imgur.com/a/ZmMzfvb

And then, a new post is added to the top https://imgur.com/a/PJ0trSF

As you'll notice the image seems to be the same, but it shouldn’t! If I scroll for a while and then go back up, the new post will be fixed and display the proper image. (I'm using SDWebImageSwiftUI for async images, but I don't think it matters... I also used Apple's AsyncImage, with the same results)

Here's my feed view model:

@Published var feedPage: Page = .first()
@Published var feedItems = Array(0..<2)

var posts = [Post]()

...

private func subscribeToNewPosts() {
    postsService.subscribeToNewPosts() { [weak self] post in
        self?.posts.insert(post, at: 0)

        DispatchQueue.main.async {
             self?.feedItems = Array(0..<(self?.posts.count ?? 1))
        }
    }
}

And here's my feed view:

private struct FeedPageView: View {
    @EnvironmentObject private var viewModel: FeedView.ViewModel

    var body: some View {
        ZStack {
            VStack {
                Pager(page: viewModel.feedPage,
                      data: viewModel.feedItems,
                      id: \.self,
                      content: { index in
                    if index == 0 {
                        HomeCameraView()
                            .background(.black)
                    } else {
                            PostView(post: viewModel.posts[index - 1])
                    }
                })
                .vertical()
                .sensitivity(.custom(0.1))
                .onPageWillChange { index in
                    viewModel.willChangeVerticalPage(index: index)
                }
            }
        }
    }
}

Any idea what I'm doing wrong?