Infinite pagination with local data

Viewed 336

I have a large data set of elements in cache that I need to show, to implement the infinite pagination I thought to do it like this:

@State var historyPagination: Int = 10
@State var didHistoryPaginationFinishLoading: Bool = false

ScrollView {
    // Some other stuff here

    LazyVStack {    
        ForEach(0..<myLocalArrayData.count) { index in
            if(index < historyPagination) {
                MyView(data: data)        
            }
        }      

        LazyVStack {
            if (historyPagination < myLocalArrayData.count) {
                if(!didHistoryPaginationFinishLoading) {
                    ProgressView()
                            .onAppear {
                                // Execute code with delay
                                DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                                    historyPagination += 10
                                    didHistoryPaginationFinishLoading = true
                                }
                            }
                            .onDisappear {
                                if (historyPagination < myLocalArrayData.count) {
                                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                                        didHistoryPaginationFinishLoading = false
                                    }
                                }
                            }
                            .padding(.vertical)
                }
            }
        }
    }
}

The problem I'm having is that when it gets to the bottom part the spining animation doesn't go away and if I scroll a little bit up and then down I can see when I print the values that historyPagination keeps being added +10 automatically.

EDIT:

This glitch seems to only happen after certain amount of data, for example I tested it with 40 items and works fine, but if I have 200 items it seems bugged. Is there something like with Text("") in a view that you can't have more than x amount (I don't remember how many, 5, 10?) without putting it in a Group.

1 Answers

After some hours hammering the code I found the problem to be in the LazyView. This combo is a bit bugged at the moment: ScrollView + LazyVStack + OnAppear

I removed the LazyVStack from the foreach and it worked as expected. I leave it there once it passes more or less the 40 count in the index it starts loading by itself (very weird behavior...)

This is how the code looks at the end (I think my implementation of loading local data is VERY rustic, if someone wants to improve it please do so)

ScrollView {
    // Some other stuff here

    ForEach(0..<myLocalArrayData.count) { index in
        if(index < historyPagination) {
            MyView(data: data)        
        }
    }      

    LazyVStack {
        if (historyPagination < myLocalArrayData.count) {
            if(!didHistoryPaginationFinishLoading) {
                ProgressView()
                        .onAppear {
                            // Execute code with delay
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                                historyPagination += 10
                                didHistoryPaginationFinishLoading = true
                            }
                        }
                        .onDisappear {
                            if (historyPagination < myLocalArrayData.count) {
                                DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                                    didHistoryPaginationFinishLoading = false
                                }
                            }
                        }
                        .padding(.vertical)
            }
        }
    }
}
Related