Ios 如何正确插入或删除UICollectionView补充视图
简短问题: 是否有一种方法可以添加和删除类似于Ios 如何正确插入或删除UICollectionView补充视图,ios,objective-c,uicollectionview,uicollectionviewlayout,uicollectionreusableview,Ios,Objective C,Uicollectionview,Uicollectionviewlayout,Uicollectionreusableview,简短问题: 是否有一种方法可以添加和删除类似于插入项扩展路径:删除项扩展路径:或甚至重新加载项扩展路径:方法的性能更新:块中的单元格和节等补充视图 详细解释: 我对节使用UICollectionView。这些单元像网格一样布置,每条线最多可以有6个单元。如果单元格的总数没有填满一个部分的所有行,我会添加额外的补充视图。附加的补充视图只是填补了空白。因此,结果应该是每个部分都被所有可用的单元完全填充,并且(可能)剩余的空白点被补充视图填充。因此,每行有6个视觉元素,即一个单元或一个补充视图 为了实
插入项扩展路径:
删除项扩展路径:
或甚至重新加载项扩展路径:
方法的性能更新:
块中的单元格和节等补充视图
详细解释:
我对节使用UICollectionView
。这些单元像网格一样布置,每条线最多可以有6个单元。如果单元格的总数没有填满一个部分的所有行,我会添加额外的补充视图。附加的补充视图只是填补了空白。因此,结果应该是每个部分都被所有可用的单元完全填充,并且(可能)剩余的空白点被补充视图填充。因此,每行有6个视觉元素,即一个单元或一个补充视图
为了实现这一点,我使用以下prepareLayout:
实现了基于自定义UICollectionViewFlowLayout
的布局:
- (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];
}
}
}
}
}
-(无效)准备就绪{
[超级准备];
self.supplementaryViewAttributeList=[NSMutableArray];
if(self.collectionView!=nil){
//计算布局值
CGFloat contentWidth=self.collectionViewContentSize.width-self.sectionInset.left-self.sectionInset.right;
CGFloat cellSizeWithSpacing=self.itemSize.width+self.MinimumInTerminItemSpacing;
NSInteger numberOfItemsPerLine=楼层(内容宽度/单元大小与间距);
CGFloat realInterItemSpacing=(contentWidth-(numberOfItemsPerLine*self.itemSize.width))/(numberOfItemsPerLine-1);
//添加补充属性
对于(NSInteger numberOfSection=0;numberOfSection0&&NumberOfSupplementaryView<6){
NSIndexPath*indexPathOfLastCellOfSection=[NSIndexPath indexPathForItem:(numberOfItems-1)inSection:numberOfSection];
UICollectionViewLayoutAttributes*layoutAttributesOfLastCellOfSection=[ItemAtIndexPath:indexPathOfLastCellOfSection的自布局属性];
对于(NSInteger numberOfSupplementor=0;numberOfSupplementor
如果所有数据从一开始就可用,并且数据没有变化,则此操作非常有效。但是,如果数据在生命周期内被添加和删除,它将失败得很惨。在性能更新:
中插入和删除单元格会弄乱补充视图
应该发生什么:
对于使用insertitemsatindexpath插入的每个单元格:
应删除位于同一indexPath
位置的补充视图。此外,对于使用deleteeitemsatindexpath:
删除的每个单元格,应在同一indexPath
处添加新的补充视图
问题:
调用我的布局的prepareLayout:
,并计算正确的layoutAttribute
。但是,对于怪异的indexpath
调用了layouttributesforSupplmentaryViewofKind:atIndexPath:
。具体地说,为从补充视图属性列表
数组中删除的旧索引路径
调用了layouttributesforSupplmentaryViewofKind:atIndexPath:
示例:
在插入新单元格的情况下,prepareLayout:
会正确删除layouttributes
,但对于不再可用且已删除的indexPath,仍会调用layouttributes for SupplementaryViewofKind:atIndexPath:
!只有这样。对于所有其他补充视图,不需要额外调用任何其他indepath
s
为什么对不再可用的indexpath
调用了种类为:aIndexPath:的Supplmentary视图的LayoutAttribute?如何正确删除、插入或重新加载补充视图?我错过了什么
来源:
完整来源可在此处找到:
自定义布局:
CollectionView控制器:
(performBatchUpdates:
在类的最后一个方法中)一个解决方案是向performBatchUpdates:
块添加[[collectionView collectionViewLayout]invalidateLayout]
。这会迫使布局重新计算并删除无效的索引路径。你的评论对我来说并不是什么窍门,我找到了另一段代码并添加了它,它成功了,甚至删除了上面的建议,它仍然有效。有限公司
- (NSArray<NSIndexPath *> *)indexPathsToDeleteForSupplementaryViewOfKind:(NSString *)elementKind
{
return self.removedIndexPaths;
}