11.8 C
New York
Wednesday, December 18, 2024

ios – Pagination for GridView utilizing SwiftUI


I create a pagination display screen utilizing TMDb api in SwiftUI for GridView :

var physique: some View {
        ZStack {
            ScrollView {
                LazyVGrid(columns: [GridItem(.adaptive(minimum: Constants.gridItemSize))]) {
                    ForEach(viewModel.motion pictures, id: .self.id) { film in
                        MovieColumn(film: film).onAppear {
                            if film == viewModel.motion pictures.final, viewModel.hasMoreData {
                                Job {
                                    await viewModel.loadMoreData()
                                }
                            }
                        }
                    }
                }
                if(!viewModel.motion pictures.isEmpty) {
                    Spacer()
                    loadingOrErrorView
                }
            }
            if(viewModel.motion pictures.isEmpty) {
                loadingOrErrorView
            }
        }.process {
            await viewModel.loadMoreData()
        }
    }
    
    @ViewBuilder
    non-public var loadingOrErrorView: some View {
        change viewModel.viewState {
        case .loading:
            ProgressView()
        case .failure(let error):
            errorView(error: error)
        case .idle:
            EmptyView()
        }
    }
    
    non-public func errorView(error: Error) -> some View {
        VStack {
            Textual content(error.localizedDescription)
                .foregroundColor(.purple)
                .multilineTextAlignment(.middle)
                .padding()
            
            Button(motion: {
                Job {
                    await viewModel.loadMoreData()
                }
            }) {
                Textual content("Retry")
                    .padding()
                    .background(Colour.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }
        }
    }

And right here is my ViewModel :

@Observable
class PaginationViewModel {
    var motion pictures: [Movie] = []
    var hasMoreData = true
    var viewState: ViewState = .idle
    
    @ObservationIgnored
    non-public var currentPage = 1
    
    @ObservationIgnored
    non-public let networkService: NetworkService
    
    init(networkService: NetworkService) {
        self.networkService = networkService
    }
    
    @MainActor
    func loadMoreData() async {
        guard viewState != .loading && hasMoreData else { return }
        self.viewState = .loading
        do {
            let request = TMDbRequest(path: .motion pictures, web page: currentPage)
            let newItems: TMDbWrapper = strive await networkService.carry out(request: request)
            self.motion pictures.append(contentsOf: newItems.motion pictures)
            self.currentPage += 1
            self.hasMoreData = newItems.motion pictures.rely == Constants.PAGE_SIZE
            self.viewState = .idle
        } catch {
            self.viewState = .failure(error: error)
        }
    }
    
    non-public struct Constants {
        static let PAGE_SIZE = 20
    }
}

enum ViewState: Equatable {
    case idle
    case loading
    case failure(error: Error)
    
    static func == (lhs: ViewState, rhs: ViewState) -> Bool {
        change (lhs, rhs) {
        case (.idle, .idle): return true
        case (.loading, .loading): return true
        case (.failure(error: _), .failure(error: _)): return true
        default: return false
        }
    }
}

As you see I’ve applied loading and error view logic in two completely different place. One for preliminary state and one for loading subsequent web page. Is there any resolution to enhance this logic whereas utilizing GridView? I additionally marvel if in case you have a extra optimize resolution for Pagination in SwiftUI?

Supply code : https://github.com/alirezaeiii/Pagination-Task/tree/major

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles