插入包含页脚的UICollectionView部分的问题

Vap*_*olf 9 ios uicollectionview uicollectionviewlayout uicollectionreusableview

我有一个典型的UICollectionView,它以垂直方式使用UICollectionViewFlowLayout.我正在使用带有分页的rest API来填充集合视图.为了触发下一页下载,我在使用委托时要求页脚布局:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
    RDLoadMoreReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"RDLoadMoreReusableView" forIndexPath:indexPath];
    view.delegate = self;
    [view start];
    [self loadNextPageOfAssets];
    return view;
}
Run Code Online (Sandbox Code Playgroud)

这是我的loadNextPageOfAssets背后的代码:

-(void)loadNextPageOfAssets{
    __weak RDRadiusGridViewController *weakSelf = self;

    // Increment page and request assets. They are added to cluster.assets before the completion block is called.
    self.cluster.pagination.page++;
    [self.cluster requestAssetsWithCompletionBlock:^(NSArray *assets) {

        SM_LOG_DEBUG(@"page.total: %ld assets.count: %ld", self.cluster.pagination.totalCount, (long)assets.count);

        NSMutableArray *indexPaths = [[NSMutableArray alloc]initWithCapacity:assets.count];
        for(NSUInteger index = 0; index < assets.count; index++){
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.cluster.assets.count - assets.count + index inSection:0];
            SM_LOG_DEBUG(@"Inserting indexPath: %ld:%ld", (long)indexPath.item, (long)indexPath.section);
            [indexPaths addObject:indexPath];
        }
        [weakSelf.collectionView performBatchUpdates:^{
            [weakSelf.collectionView insertItemsAtIndexPaths:indexPaths];
        } completion:^(BOOL finished) {

        }];

//            [weakSelf.collectionView reloadData];
    }];
}
Run Code Online (Sandbox Code Playgroud)

当我运行时,我可以转到我的ViewController并查看加载的资产的第一页.如果我向下滚动,我将看到页脚视图(包含一个微调器),但代码将在行的异常断点处中断:

[weakSelf.collectionView insertItemsAtIndexPaths:indexPaths];
Run Code Online (Sandbox Code Playgroud)

断言失败 - [UICollectionViewData layoutAttributesForSupplementaryElementOfKind:atIndexPath:],/ SourceCache/UIKit/UIKit-3185.20/UICollectionViewData.m:829


然后,如果我继续它崩溃与错误:

2014-06-11 16:39:58.335 Radius-iOS [4901:525006] *由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'没有UICollectionViewLayoutAttributes实例用于-layoutAttributesForSupplementaryElementOfKind:路径中的UICollectionElementKindSectionFooter {length = 2,path = 0 - 0}'*第一次抛出调用堆栈:


这对我来说很困惑.layoutAttributesForSupplementaryElementOfKind听起来像是与布局类有关,但我没有使用自定义流布局而是提供默认布局.听起来Apple的代码很疯狂,但我觉得我正在使用一切.

现在,如果我移动电话:

[self loadNextPageOfAssets];
Run Code Online (Sandbox Code Playgroud)

从补充单元格出列到UICollectionViewCell deque,并将页脚视图全部删除,然后插入工作很好.

现在我正在调用reloadData而不是insert,但这是UGLY.

我是否忽略了有关页脚的内容?

Joh*_*nes 10

VaporwareWolf提供的答案有点像黑客.通过返回一个小尺寸而不是零尺寸,补充视图将始终存在但尺寸太小而无法看到.这就是为什么它修复了NSInternalInconsistencyException

但是,有一个真正的解决方案.

之后将数据添加到数据源和 之前打电话insertItemsAtIndexPaths,刚上的CollectionView布局失效,使其意识到的变化.

Objective-C的

[self.collectionView.collectionViewLayout invalidateLayout]
Run Code Online (Sandbox Code Playgroud)

迅速

collectionView.collectionViewLayout.invalidateLayout()
Run Code Online (Sandbox Code Playgroud)


Vap*_*olf 9

事实证明我实际上遇到了布局问题(正如错误描述所示)

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{
    if(<myDecision>){
        return CGSizeZero;
    } else {
        return CGSizeMake(320, 50);
    }
}
Run Code Online (Sandbox Code Playgroud)

CGSizeZero是导致崩溃的原因.而是使用CGSizeMake(0.001,0.001).这是唯一必要的改变.它现在按预期运行.