#json #swift #pagination #infinite-scroll
#json #swift #разбивка на страницы #бесконечная прокрутка
Вопрос:
с помощью этого json кажется, что я не могу выполнить простое добавление массива, потому что разбивка на страницы работает только с количеством страниц. Как я могу добавить бесконечную прокрутку / разбивку на страницы со страницами? Теперь страница 1 загружается с 20 элементами, это работает, но как я могу загрузить другие страницы и сохранить ранее загруженные?
Прямо сейчас мой VC выглядит так:
import UIKit
struct SwiftData: Codable {
let results: [Results]
}
struct Results: Codable {
let title: String?
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var popularMoviesArray = [Results]()
var tableViewCell = TableViewCell()
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
swiftManager.fetchUrl()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return popularMoviesArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: ConstantFile.cellIdentifier, for: indexPath) as! TableViewCell
var item: Results
item = popularMoviesArray[indexPath.row]
cell.labelTitle.text = item.title
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: ConstantFile.performSegueIdentifier, sender: indexPath.row)
tableView.deselectRow(at: indexPath, animated: true)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier != nil else {
return
}
let letRow = sender as? Int
switch segue.identifier {
case "goToDetail":
(segue.destination as! ViewControllerDetail).itemDetail = popularMoviesArray[letRow!]
default:
return
}
}
}
struct SwiftManager {
let baseURL = "https://api.themoviedb.org/3/movie/popular"
let apiKey = “xxxxxxxxxxxxxx”
let filterURL1 = "language=en-US"
let filterURL2 = "sort_by=popularity.desc"
let filterURL3 = "page=1"
func fetchUrl() {
let urlString = "(baseURL)?api_key=(apiKey)amp;(filterURL1)amp;(filterURL2)amp;(filterURL3)"
performRequest(with: urlString)
}
func performRequest(with urlString: String) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
self.delegate?.didFailWithError(error: error!)
return
}
if let safeData = data {
if let movies = self.parseJSON(safeData) {
self.delegate?.didUpdateStruct(self, swiftData: movies)
}
}
}
task.resume()
}
}
func parseJSON(_ swiftData: Data) -> SwiftData? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(SwiftData.self, from: swiftData)
return decodedData
} catch {
print(error)
return nil
}
}
}
Ответ №1:
Вы можете видеть, что достигли нижней части списка с willDisplay
помощью функции из UITableViewDelegate
протокола. как показано ниже, код:
public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forItemAt indexPath: IndexPath) {
let lastIndex = self.popularMoviesArray.count - 1
if indexPath.row == lastIndex {
// api call and get next page
}
}
и вы можете вызвать API для получения данных следующей страницы.
затем добавьте новые данные в свой список источников данных и перезагрузите TableView:
self.popularMoviesArray.append(contentsOf: newListData)
self.tableView.reloadData()
Комментарии:
1. Привет @hessam эти две строки в какой момент кода они должны быть вставлены? self.popularMoviesArray.append(contentsOf: newListData) и self.TableView.reloadData()
2. Ровно после того, как с сервера пришел ответ, вы и вы получили новые данные. если пусть movies = self.parseJSON(safeData) { … } например, как здесь .
3. извините, последний вопрос 🙂 newListData что это такое, откуда я могу его получить? Спасибо
4. нет проблем 🙂 newListData Пример. Это означает
newdata
, что с сервера. внутриperformRequest
вы вызываете API и получаете ответ от сервера. newListData похожа на decodedData. Если вы не понимаете моего объяснения, скажите мне, что я имею в виду, чтобы отправить вам пример кода.5. теперь я понимаю, и это, наконец, работает! Спасибо!