ios - 使用 JSON 快速分页
问题描述
我对 JSON 数据的分页有一些问题。我只能显示一页,但我需要在最后一个单元格时显示下一页。
我已经用 willDisplay 尝试过这种方式,但它没有用。我想我需要将我的数据保存在某个数组中,但是我不知道该怎么做。我也有来自 JSON 的数据模型。请帮助我,分页让我发疯:(
请不要注意 viewDidLoad 中的 func getDate,这是另一个问题:D
import UIKit
class FilmsViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var searchController: UISearchController!
var films = Films()
var page = 1
override func viewDidLoad() {
super.viewDidLoad()
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
tableView.tableHeaderView = searchController.searchBar
tableView.reloadData()
getDate(title: "World", page: page)
}
private let endPoint = "http://www.omdbapi.com/"
func getDate(title: String, page: Int) {
var urlComponents = URLComponents(string: endPoint)
let querySearchNameOfFilm = URLQueryItem(name: "s", value: title)
let querytypeOfFilms = URLQueryItem(name: "type", value: "movie")
let queryPages = URLQueryItem(name: "page", value: String(page))
let queryApiKey = URLQueryItem(name: "apikey", value: "a6c7f954")
urlComponents?.queryItems = [querySearchNameOfFilm,
querytypeOfFilms,
queryPages,
queryApiKey]
guard let url = urlComponents?.url else { return }
let session = URLSession.shared
session.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
do {
self.films = try JSONDecoder().decode(Films.self, from: data)
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print(error)
}
}.resume()
}
// MARK: - Cells
func configureCell(cell: FilmsCell, for indexPath: IndexPath) {
guard let search = self.films.search else { return }
let films = search[indexPath.row]
cell.titleFilmLabel.text = films.title
if let imageUrl = URL(string: films.poster!) {
DispatchQueue.global().async {
guard let data = try? Data(contentsOf: imageUrl) else { return }
let image = UIImage(data: data)
DispatchQueue.main.async {
cell.imageFilm.image = image
}
}
}
}
}
extension FilmsViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
getDate(title: searchController.searchBar.text!, page: page)
}
}
extension FilmsViewController: UITableViewDelegate {
}
extension FilmsViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let search = self.films.search else { return 20 }
return search.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FilmsCell
configureCell(cell: cell, for: indexPath)
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let search = self.films.search {
if indexPath.row == search.count - 1 {
page += 1
getDate(title: searchController.searchBar.text!, page: page)
}
}
}
}
解决方案
我在所有项目中都采用这种有用的方式。当用户到达 tableview 的末尾时,我调用 api 来获取数据。
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let height = scrollView.frame.size.height
let contentYoffset = scrollView.contentOffset.y
let distanceFromBottom = scrollView.contentSize.height - contentYoffset
if distanceFromBottom < height { // when you reach the bottom
page += 1
getDate(title: searchController.searchBar.text!, page: page)
}
}
推荐阅读
- angular - jhipster 和主细节
- html - CSS:字体问题 - Ubuntu Condensed Font 有时无法正确呈现
- javascript - 获取 CSRF 令牌不匹配 Laravel
- jenkins - Jenkins Pipeline Plugin 执行外部步骤
- android - 如何在android中实现jwplayer的破折号视频流
- javascript - 如何使用 Nodemailer 发送带有公司域的电子邮件?
- python - pandas:通过将两列数据框与元组列表进行比较来获取行
- sql - 带有嵌套节点的sql xml
- java - 找到第一个匹配的条目并将匹配的条目值分配给变量
- javascript - 将第三方库组装成单独的文件(webpack)