[英]UICollectionView attempts to dequeue cells beyond data source bounds while reordering is in progress
我已经实现了单元格重新排序的集合视图
class SecondViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
private var numbers: [[Int]] = [[], [], []]
private var longPressGesture: UILongPressGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
for j in 0...2 {
for i in 0...5 {
numbers[j].append(i)
}
}
longPressGesture = UILongPressGestureRecognizer(target: self, action: "handleLongGesture:")
self.collectionView.addGestureRecognizer(longPressGesture)
}
func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case .Began:
guard let selectedIndexPath = self.collectionView.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else {
break
}
collectionView.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
case .Changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
case .Ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
}
extension SecondViewController: UICollectionViewDataSource {
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return numbers.count
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let number = numbers[section].count
print("numberOfItemsInSection \(section): \(number)")
return number
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
print("cellForItemAtIndexPath: {\(indexPath.section)-\(indexPath.item)}")
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! TextCollectionViewCell
cell.textLabel.text = "\(numbers[indexPath.section][indexPath.item])"
return cell
}
func collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
let temp = numbers[sourceIndexPath.section].removeAtIndex(sourceIndexPath.item)
numbers[destinationIndexPath.section].insert(temp, atIndex: destinationIndexPath.item)
}
}
在我尝试将项目从第0部分拖动到第2部分(不在屏幕上)之前,它工作正常。 当我将项目拖到集合视图的底部时,它会慢慢开始向下滚动。 在某个时刻(滚动到第1节时),应用程序崩溃并出现fatal error: Index out of range
因为它试图在第1节中的索引6处请求单元格,而本节中只有6个项目。 如果我尝试将项目从第1部分拖到第2部分,则一切正常。
这是一个重现此问题的示例项目( 贷给NSHint ): https : //github.com/deville/uicollectionview-reordering
这是框架中的错误还是我缺少什么? 如果是前者,那么解决方法是什么?
我今天实际上遇到了这个问题。 最终问题出在itemAtIndexPath中-我引用数据源来获取单元格的某些属性:因此,超出范围的源崩溃了。 对我来说,解决方法是在itemAtIndexPath中保留对当前拖动单元格的引用。 检查节的数据源长度与传递的NSIndexPath的比较,以及是否超出范围; 请参考拖动单元格的属性。
Likesuchas(在Obj-C中……尚未移至Swift):
NSArray* sectionData = [collectionViewData objectAtIndex:indexPath.section];
MyObject* object;
if (indexPath.row < [sectionData count]) {
object = [dataObject objectAtIndex:indexPath.row];
} else {
object = draggingCell.object;
}
[cell configureCell:object];
不知道这是否与您的确切问题相似; 但是这是我的,因为现在一切都按预期进行。 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.