Бесконечная прокрутка страницы TableView

#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. теперь я понимаю, и это, наконец, работает! Спасибо!