简短的问题:
有没有办法在performBatchUpdates:
块中添加和删除补充视图,如单元格和部分,类似于insertItemsAtIndexPaths:
deleteItemsAtIndexPaths:
甚至reloadItemsAtIndexPaths:
方法?
长解释:
我使用UICollectionView
with 部分。单元格像网格一样布置,每行最多可以有 6 个单元格。如果单元格的总数没有填满一个部分的所有行,我会添加额外的补充视图。额外的补充视图只是填补了空白。所以结果应该是每个部分都完全填充了所有可用的单元格,并且(可能的)剩余的空白点填充了补充视图。所以每行有 6 个视觉元素,一个单元格或一个补充视图。
为了实现这一点,我UICollectionViewFlowLayout
使用以下实现实现了一个基于自定义的布局prepareLayout:
:
- (void)prepareLayout {
[super prepareLayout];
self.supplementaryViewAttributeList = [NSMutableArray array];
if(self.collectionView != nil) {
// calculate layout values
CGFloat contentWidth = self.collectionViewContentSize.width - self.sectionInset.left - self.sectionInset.right;
CGFloat cellSizeWithSpacing = self.itemSize.width + self.minimumInteritemSpacing;
NSInteger numberOfItemsPerLine = floor(contentWidth / cellSizeWithSpacing);
CGFloat realInterItemSpacing = (contentWidth - (numberOfItemsPerLine * self.itemSize.width)) / (numberOfItemsPerLine - 1);
// add supplementary attributes
for (NSInteger numberOfSection = 0; numberOfSection < self.collectionView.numberOfSections; numberOfSection++) {
NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:numberOfSection];
NSInteger numberOfSupplementaryViews = numberOfItemsPerLine - (numberOfItems % numberOfItemsPerLine);
if (numberOfSupplementaryViews > 0 && numberOfSupplementaryViews < 6) {
NSIndexPath *indexPathOfLastCellOfSection = [NSIndexPath indexPathForItem:(numberOfItems - 1) inSection:numberOfSection];
UICollectionViewLayoutAttributes *layoutAttributesOfLastCellOfSection = [self layoutAttributesForItemAtIndexPath:indexPathOfLastCellOfSection];
for (NSInteger numberOfSupplementor = 0; numberOfSupplementor < numberOfSupplementaryViews; numberOfSupplementor++) {
NSIndexPath *indexPathOfSupplementor = [NSIndexPath indexPathForItem:(numberOfItems + numberOfSupplementor) inSection:numberOfSection];
UICollectionViewLayoutAttributes *supplementaryLayoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:ARNCollectionElementKindFocusGuide withIndexPath:indexPathOfSupplementor];
supplementaryLayoutAttributes.frame = CGRectMake(layoutAttributesOfLastCellOfSection.frame.origin.x + ((numberOfSupplementor + 1) * (self.itemSize.width + realInterItemSpacing)), layoutAttributesOfLastCellOfSection.frame.origin.y, self.itemSize.width, self.itemSize.height);
supplementaryLayoutAttributes.zIndex = -1;
[self.supplementaryViewAttributeList addObject:supplementaryLayoutAttributes];
}
}
}
}
}
如果从一开始所有数据都可用并且数据没有更改,则此方法非常有用。但是,如果在生命周期内添加和删除数据,它就会惨遭失败。performBatchUpdates:
在补充视图中插入和删除单元格。
应该发生什么:
对于与insertItemsAtIndexPaths:
补充视图同时插入的每个单元格,indexPath
都应删除。此外,对于使用新补充视图删除的每个单元格,deleteItemsAtIndexPaths:
应同时添加indexPath
。
问题:
调用我的prepareLayout:
布局并计算正确的layoutAttributes
. 但layoutAttributesForSupplementaryViewOfKind:atIndexPath:
被称为怪异indexPaths
。特别是从数组中删除layoutAttributesForSupplementaryViewOfKind:atIndexPath:
的 old 被调用!indexPaths
supplementaryViewAttributeList
例子:
在插入新单元格的情况下,prepareLayout:
正确删除layoutAttributes
,但layoutAttributesForSupplementaryViewOfKind:atIndexPath:
仍然会调用不再可用和删除的 indexPath!仅此而已。indexPath
对于所有其他补充观点,没有额外的要求。
为什么layoutAttributesForSupplementaryViewOfKind:atIndexPath:
要求indexPaths
不再可用?如何正确删除、插入或重新加载补充视图?我想念什么?
来源:
完整的来源可以在这里找到:
CollectionView 控制器:
https ://github.com/sarn/ARNClassicFilms/blob/master/classicFilms/classicFilms/view-controllers/ARNMovieOverviewController.m
(performBatchUpdates:
在类的最后一个方法中)