CollectionView error : attempt to insert item 40 into section 0, but there are only 40 items in section 0 after the update
CollectionView error : attempt to insert item 40 into section 0, but there are only 40 items in section 0 after the update
集合视图将显示 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: [=11=], 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() 内部,但即使我这样做了,错误仍然存在。可能是我执行不当。
错误总是:
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'attempt to insert item 40
into section 0, but there are only 40 items in section 0 after the
update'
也许任何人都可以展示似乎是问题的部分?
数组的最后一个索引是.count - 1
。您必须使用 ..<
运算符
let indexPaths = Array(lastInArray..<newLastInArray).map{IndexPath(item: [=10=], section: 0)}
并且不需要 performBatchUpdates
块,它仅对同时 insert/delete/move 操作有用
DispatchQueue.main.async {
self.moviesCV.insertItems(at: indexPaths)
}
集合视图将显示 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: [=11=], 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() 内部,但即使我这样做了,错误仍然存在。可能是我执行不当。
错误总是:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert item 40 into section 0, but there are only 40 items in section 0 after the update'
也许任何人都可以展示似乎是问题的部分?
数组的最后一个索引是.count - 1
。您必须使用 ..<
运算符
let indexPaths = Array(lastInArray..<newLastInArray).map{IndexPath(item: [=10=], section: 0)}
并且不需要 performBatchUpdates
块,它仅对同时 insert/delete/move 操作有用
DispatchQueue.main.async {
self.moviesCV.insertItems(at: indexPaths)
}