-1

集合视图将显示 20 部电影的列表,如果用户滚动到最后一个项目,那么它将加载另外 20 个。起初我在将另外 20 个项目附加到电影数组后使用了 reloadData(),它可以工作。但我相信正确的做法是将insertItems() 插入collectionView,而不是每次都调用reloadData()。在我实现了 insertItems() 之后,就会出现错误。

这是与 CollectionView 相关的代码:

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return moviesArray.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MovieCell", for: indexPath) as! MovieCell
        let imageUrl = moviesArray[indexPath.row].posterPath!
        let url = URL(string: "https://image.tmdb.org/t/p/w500\(imageUrl)")!
        cell.moviePoster.load(url: url)
        cell.layer.cornerRadius = 10
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        if indexPath.row == moviesArray.count - 1 {
            currentPage += 1
            dataManager.downloadAllMoviesJSON(page: currentPage)
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        dataManager.downloadMovieDetailJSON(id: moviesArray[indexPath.row].id) { (data) in
            DispatchQueue.main.async {
                self.performSegue(withIdentifier: "ToMovieDetail", sender: self)
            }
        }

这是处理电影列表加载和附加的代码:

    func didGetMovies(dataManager: DataManager, movie: MovieData) {
        if currentPage > 1 {
            let lastInArray = moviesArray.count
            self.moviesArray.append(contentsOf: movie.results)
            let newLastInArray = moviesArray.count
            let indexPaths = Array(lastInArray...newLastInArray).map{IndexPath(item: $0, section: 0)}
            DispatchQueue.main.async {
                self.moviesCV.performBatchUpdates({
                    self.moviesCV.insertItems(at: indexPaths)
                }, completion: nil)
            }
        } else {
            moviesArray = movie.results
            DispatchQueue.main.async {
                self.moviesCV.reloadData()
            }
        }
    }

起初我不知道 insertItems() 必须在 performBatchUpdates() 内,但即使我这样做,错误仍然存​​在。可能是因为我实施不当。

错误总是:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“尝试将第 40 项插入第 0 节,但更新后第 0 节中只有 40 项”

也许任何人都可以友好地展示似乎是问题的部分?

4

1 回答 1

1

数组的最后一个索引是.count - 1。您必须使用..<运算符

let indexPaths = Array(lastInArray..<newLastInArray).map{IndexPath(item: $0, section: 0)}

并且performBatchUpdates不需要该块,它仅对同时插入/删除/移动操作有用

DispatchQueue.main.async { 
    self.moviesCV.insertItems(at: indexPaths) 
}
  
于 2020-06-22T04:46:55.313 回答