Ios 从自定义UICollectionView(如Pinterest)中删除单元格
我有一个像Pinterest一样定制的UICollectionView。我归档了以下内容。我做的每件事都和这里一模一样,而且效果很好。尝试从集合视图中删除单元格时出现问题。我使用此功能进行删除:Ios 从自定义UICollectionView(如Pinterest)中删除单元格,ios,swift,uicollectionview,pinterest,Ios,Swift,Uicollectionview,Pinterest,我有一个像Pinterest一样定制的UICollectionView。我归档了以下内容。我做的每件事都和这里一模一样,而且效果很好。尝试从集合视图中删除单元格时出现问题。我使用此功能进行删除: extension PintViewController:FavouriteOffersDelegate{ func collectionViewCellDidTapHeart(_ sender: PntCollectionViewCell) { guard let indexTapped =
extension PintViewController:FavouriteOffersDelegate{
func collectionViewCellDidTapHeart(_ sender: PntCollectionViewCell) {
guard let indexTapped = collectionView.indexPath(for: sender) else {
return
}
let id:Int = generalsOffersArray[indexTapped.row].id
print(indexTapped.item)
generalsOffersArray.remove(at: indexTapped.item)
collectionView.deleteItems(at: [indexTapped])
}
}
我知道问题一定是在我使用的库中,但我是Swift的新手,不能清楚地理解我应该修改或删除什么才能使其正常工作。执行此代码时,控制台中出现的错误为:
2017-10-18 17:25:20.637123+0200 RemoveItemsPinterest[1017:432532]*在-[UICollectionViewData validateLayoutInRect:],/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3694.4.18/UICollectionViewData.m:435中断言失败
2017-10-18 17:25:20.638356+0200 RemoveItemsPinterest[1017:432532]*由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“UICollectionView接收到索引路径不存在的单元格的布局属性:{length=2,path=0-12}”
***第一次抛出调用堆栈:
(0x1833bfd38 0x1828d4528 0x1833bfc0c 0x183d4ec24 0x18c82b834 0x18c82ab8c 0x18d2964ac 0x18d2412b8 0x18d241218 0x18d241148 0x18c82a1cc 0x18c7cd000 0x18739d0b4 0x1873a1194 0x18730ff24 0x187336340 0x18ca33744 0x18d112718 0x18D10B5774 0x183368358 0x1833682d8 0x183367b60 0x365738 0x1832862d8 0x1873A1874 0x1878EA388C1088C)
libc++abi.dylib:以NSException类型的未捕获异常终止
布局对象的代码:
class PinterestLayout: UICollectionViewLayout {
var delegate:PinterestLayoutDelegate!
var numberOfColumns = 2
var cellPadding: CGFloat = 5.0
fileprivate var cache = [PinterestLayoutAttributes]()
fileprivate var contentHeight:CGFloat = 0.0
fileprivate var contentWidth: CGFloat {
let insets = collectionView!.contentInset
return collectionView!.bounds.width - (insets.left + insets.right)
}
override class var layoutAttributesClass : AnyClass {
return PinterestLayoutAttributes.self
}
override func prepare() {
if cache.isEmpty {
let columnWidth = contentWidth / CGFloat(numberOfColumns)
var xOffset = [CGFloat]()
for column in 0 ..< numberOfColumns {
xOffset.append(CGFloat(column) * columnWidth )
}
var column = 0
var yOffset = [CGFloat](repeating: 0, count: numberOfColumns)
for item in 0 ..< collectionView!.numberOfItems(inSection: 0) {
let indexPath = IndexPath(item: item, section: 0)
let width = columnWidth - cellPadding*2
let photoHeight = delegate.collectionView(collectionView!, heightForPhotoAtIndexPath: indexPath , withWidth:width)
let annotationHeight = delegate.collectionView(collectionView!, heightForAnnotationAtIndexPath: indexPath, withWidth: width)
let height = cellPadding + photoHeight + annotationHeight + cellPadding
let frame = CGRect(x: xOffset[column], y: yOffset[column], width: columnWidth, height: height)
let insetFrame = frame.insetBy(dx: cellPadding, dy: cellPadding)
let attributes = PinterestLayoutAttributes(forCellWith: indexPath)
attributes.photoHeight = photoHeight
attributes.frame = insetFrame
cache.append(attributes)
contentHeight = max(contentHeight, frame.maxY)
yOffset[column] = yOffset[column] + height
column = column >= (numberOfColumns - 1) ? 0 : column + 1
}
}
}
override var collectionViewContentSize : CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var layoutAttributes = [UICollectionViewLayoutAttributes]()
// Loop through the cache and look for items in the rect
for attributes in cache {
if attributes.frame.intersects(rect ) {
layoutAttributes.append(attributes)
}
}
return layoutAttributes
}
}
class PinterestLayout:UICollectionViewLayout{
var委托:PinterestLayoutDelegate!
var numberOfColumns=2
变量cellPadding:CGFloat=5.0
fileprivate变量缓存=[PinterestLayoutAttributes]()
fileprivate var contentHeight:CGFloat=0.0
fileprivate var contentWidth:CGFloat{
让insets=collectionView!.contentInset
返回collectionView!.bounds.width-(insets.left+insets.right)
}
重写类变量LayoutAttributeClass:AnyClass{
return pinterestlayouttributes.self
}
重写func prepare(){
如果cache.isEmpty{
让columnWidth=contentWidth/CGFloat(numberOfColumns)
var xOffset=[CGFloat]()
对于0..=(numberOfColumns-1)?0:列+1
}
}
}
覆盖变量collectionViewContentSize:CGSize{
返回CGSize(宽度:contentWidth,高度:contentHeight)
}
是否覆盖func layoutAttributesForElements(在rect:CGRect中)->[UICollectionViewLayoutAttributes]{
变量LayoutAttribute=[UICollectionViewLayoutAttribute]()
//循环缓存并在rect中查找项
用于缓存中的属性{
如果attributes.frame.intersects(rect){
layoutAttributes.append(属性)
}
}
返回布局属性
}
}
能否尝试将GeneralOfferArray.remove(at:indexTapped.item)更改为GeneralOfferArray.remove(at:indexTapped.row)?是的,我尝试过,它们都返回相同的值,但问题仍然相同。然后在删除后查看GeneralOfferArray的计数?如果使用动画删除行,数组的计数必须始终与collectionView相同。。。如果动画不重要,只需将collectionView.deleteItems(位于:[indexTapped])更改为tableView.reloadData()。此代码允许您删除一些单元格,然后它会再次崩溃,并出现相同的错误。我开始认为我应该修改的可能是我使用的库。我只是不知道我是如何编辑问题并为布局对象添加类的。你能尝试将GeneralOfferArray.remove(at:indexTapped.item)更改为GeneralOfferArray.remove(at:indexTapped.row)吗?是的,我已经尝试过了,它们都返回相同的值,还是同样的问题。然后看看删除后的GeneralOfferArray的计数?如果使用动画删除行,数组的计数必须始终与collectionView相同。。。如果动画不重要,只需将collectionView.deleteItems(位于:[indexTapped])更改为tableView.reloadData()。此代码允许您删除一些单元格,然后它会再次崩溃,并出现相同的错误。我开始认为我应该修改的可能是我使用的库。我只是不知道我是如何编辑问题并为布局对象添加类的。