我对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)
}
}
其中一个好的有效方法是在tableview中使用scrollviewDelegate。只需在viewController中添加UIScrollViewDelegate即可
//For Pagination
var isDataLoading:Bool=false
var pageNo:Int=0
var limit:Int=20
var offset:Int=0 //pageNo*limit
var didEndReached:Bool=false
override func viewDidLoad(_){
tableview.delegate=self //To enable scrollviewdelegate
}
ScrollView Delegate方法。
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("scrollViewWillBeginDragging")
isDataLoading = false
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("scrollViewDidEndDecelerating")
}
//Pagination
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
print("scrollViewDidEndDragging")
if ((tableView.contentOffset.y + tableView.frame.size.height) >= tableView.contentSize.height)
{
if !isDataLoading{
isDataLoading = true
self.pageNo=self.pageNo+1
self.limit=self.limit+10
self.offset=self.limit * self.pageNo
loadCallLogData(offset: self.offset, limit: self.limit)
}
}
}