如何使用 MovieDB API Swift 对 TableView 进行分页?
How to do pagination for a TableView with the MovieDB API Swift?
我正在尝试创建一个应用程序,用户可以在其中滚动到表格视图的底部以显示更多结果。目前根据 API 仅显示 20 项。 API 有一个页面参数,每当用户在 ViewController 中通过此滚动到底部时,我试图将其递增 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))
}
}
}
在我的服务中class我有一个属性
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()
}
如有任何帮助,我们将不胜感激。
如评论中的回答:
您正在用新数据覆盖电影。
self?.movies = movies.results
相反,您应该 add/append 接收到新数据,以便保留以前的电影记录。像
self?.movies += movies.results
对于表格视图滚动:
滞后是因为您直接从 url 加载的图像。您应该使用 SDWebImage 进行异步图片下载。
我正在尝试创建一个应用程序,用户可以在其中滚动到表格视图的底部以显示更多结果。目前根据 API 仅显示 20 项。 API 有一个页面参数,每当用户在 ViewController 中通过此滚动到底部时,我试图将其递增 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))
}
}
}
在我的服务中class我有一个属性
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()
}
如有任何帮助,我们将不胜感激。
如评论中的回答:
您正在用新数据覆盖电影。
self?.movies = movies.results
相反,您应该 add/append 接收到新数据,以便保留以前的电影记录。像
self?.movies += movies.results
对于表格视图滚动:
滞后是因为您直接从 url 加载的图像。您应该使用 SDWebImage 进行异步图片下载。