首页 > 解决方案 > 如何使用 MovieDB API Swift 为 TableView 进行分页?

问题描述

我正在尝试创建一个应用程序,用户滚动到表格视图的底部会显示更多结果。目前根据 API 仅显示 20 个项目。API 有一个页面参数,每次用户通过 ViewController 中的 this 滚动到底部时,我试图将其递增 1。端点https://api.themoviedb.org/3/movie/popular?api_key=API_KEY&language=en-US&page=1

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offsetY = scrollView.contentOffset.y

        if offsetY > (tableView.contentSize.height - 100 - scrollView.frame.size.height){
            viewModel.getMovies() { _ in
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            }
        }

在我的 ViewModel 中,我有这些发出请求的函数

    func incrementCurrentPage() -> Int {
        var number = movieDBService.currentPage
        number += 1
        return number
    }
    func getMoreMovies(completion: @escaping (Result<Void, Error>) -> Void) {
        let page = incrementCurrentPage()

        getMovies(pageNumber: page) { result in
            switch result {
            case .success():
                completion(.success(()))
            case .failure(let error):
                completion(.failure(error))
            }
        }
    }  
func getMovies(pageNumber: Int, completion: @escaping (Result<Void, Error>) -> Void) {

        movieDBService.getPopularMovies(pageNumber: pageNumber) { result in
            switch result {
            case .success(let movie):
                self?.movies = movies.results 
                    completion(.success(()))
            case .failure(let error):
                completion(.failure(error))
            }
        }
    }

在我的服务类中,我有一个属性

 var currentPage: Int = 1

和一个检索数据的函数,即


    func getPopularMovies(pageNumber: Int, completion: @escaping (Result<MovieDBModel, Error>) -> Void) {

        let url = constructMovieEndpoint(pageNumber: pageNumber)

        let task = URLSession.shared.dataTask(with: url) { data, response, error in

            guard let response = response else { return }

            guard let data = data else { completion(.failure(.noData))
                return
            }

            guard error == nil else { return }

            do {
                let decoder = JSONDecoder()
                let movieData = try decoder.decode(MovieDBModel.self, from: data)
                completion(.success(movieData))
            } catch {
                completion(.failure(.decodingError))
            }
        }
        task.resume()
    }

任何帮助,将不胜感激。

标签: swiftpaginationtableviewthemoviedb-api

解决方案


正如评论中的回答:

您正在用新数据覆盖电影。

self?.movies = movies.results

相反,您应该只添加/附加收到的新数据,以便保留以前的电影记录。就像是

self?.movies += movies.results

对于 tableview 滚动:

滞后是因为您直接从 url 加载的图像。您应该使用SDWebImage进行异步图像下载。


推荐阅读