Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 插入包含页脚的UICollectionView节时出现的问题_Ios_Uicollectionview_Uicollectionviewlayout_Uicollectionreusableview - Fatal编程技术网

Ios 插入包含页脚的UICollectionView节时出现的问题

Ios 插入包含页脚的UICollectionView节时出现的问题,ios,uicollectionview,uicollectionviewlayout,uicollectionreusableview,Ios,Uicollectionview,Uicollectionviewlayout,Uicollectionreusableview,我有一个典型的UICollectionView,它以垂直方式使用UICollectionViewFlowLayout。我正在使用带有分页的RESTAPI来填充集合视图。为了触发下一个要下载的页面,当委托要求页脚布局时,我使用委托: - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atI

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

- (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;
}
以下是我的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];
    }];
}
-[UICollectionViewData LayoutAttributes for SupplementalElement of Kind:atIndexPath:],/SourceCache/UIKit/UIKit-3185.20/UICollectionViewData.m:829中的断言失败


然后,如果我继续,它将崩溃并出现错误:

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


这让我感到困惑。layoutAttributesForSupplementaryElementOfKind听起来似乎与layout类有关,但我使用的不是自定义流布局,而是提供的默认布局。听起来苹果的代码很疯狂,但我觉得我在正确地使用一切

现在,如果我移动通话:

[self loadNextPageOfAssets];
从补充单元格出列到UICollectionViewCell出列,并一起删除页脚视图,插入效果非常好

现在我调用的是reloadData,而不是insert,但这很难看


我是否忽略了一些关于页脚的内容?

有一篇关于UICollectionView中的bug的俄文巨著:

下面是文章中的两种方法,它们可能会解决您的问题:

@try {
    [self.collectionView insertItemsAtIndexPaths:indexPaths];
}
@catch (NSException *exception) {}

您应该同时实现(页眉和页脚)方法。即使你只想要一个。看看我的代码

-(UICollectionReusableView *) collectionView:(UICollectionView *) collectionView
           viewForSupplementaryElementOfKind:(NSString *) kind
                                 atIndexPath:(NSIndexPath *) indexPath
{
    UICollectionReusableView *header = [[UICollectionReusableView alloc] init];

    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {

        header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionViewHeader" forIndexPath:indexPath];
    }
    else {
        header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"CollectionViewHeader" forIndexPath:indexPath];
    }

    return header;
}

-(CGSize) collectionView:(UICollectionView *) collectionView
                         layout:(UICollectionViewLayout *) collectionViewLayout
referenceSizeForHeaderInSection:(NSInteger) section
{
    return CGSizeMake(self.view.frame.size.width, 100);
}

-(CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    return CGSizeZero;
}

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

-(CGSize)collectionView:(UICollectionView*)collectionView布局:(UICollectionViewLayout*)collectionViewLayout引用SizeForFooterInsection:(NSInteger)部分{
if(){
返回cgizezero;
}否则{
返回CGSizeMake(320,50);
}
}

CGSizeZero是造成这次事故的原因。而是使用CGSizeMake(0.001,0.001)。这是唯一必要的改变。它现在按预期运行

VaporwareWolf提供的答案有点老套。通过返回一个很小的尺寸而不是零尺寸,补充视图将始终存在,但其尺寸太小而看不见。这就是为什么它修复了nsinternalinconsistenceexception

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

将数据添加到数据源和 在调用
InsertItemSatinExpaths
之前,只需使collectionview上的布局无效,以使其了解更改

目标-C

迅捷的


好的。。对于初学者,您可以检查传递到ViewForSupplementElementOfKind的补充元素种类感谢!有什么原因不能简单地退回CGSizeZero吗?必须处理collection view的发脾气是非常烦人的:(这非常令人沮丧,但这解决了问题,谢谢!:)我同意你的看法。自从几年前写这篇文章以来,我对UICollectionView了解了很多。将此更改为已接受的答案。谢谢您的精彩答案。我也面临同样的问题。当数据源为空时,使用默认自定义布局并为我的页脚视图返回CGSizeZero。如果我在插入或移动方法之前不调用invalidateLayout,应用程序将崩溃
[self.collectionView performBatchUpdates:^{
        [self.collectionView reloadData];
    } completion:nil];
-(UICollectionReusableView *) collectionView:(UICollectionView *) collectionView
           viewForSupplementaryElementOfKind:(NSString *) kind
                                 atIndexPath:(NSIndexPath *) indexPath
{
    UICollectionReusableView *header = [[UICollectionReusableView alloc] init];

    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {

        header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionViewHeader" forIndexPath:indexPath];
    }
    else {
        header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"CollectionViewHeader" forIndexPath:indexPath];
    }

    return header;
}

-(CGSize) collectionView:(UICollectionView *) collectionView
                         layout:(UICollectionViewLayout *) collectionViewLayout
referenceSizeForHeaderInSection:(NSInteger) section
{
    return CGSizeMake(self.view.frame.size.width, 100);
}

-(CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    return CGSizeZero;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{
    if(<myDecision>){
        return CGSizeZero;
    } else {
        return CGSizeMake(320, 50);
    }
}
[self.collectionView.collectionViewLayout invalidateLayout]
collectionView.collectionViewLayout.invalidateLayout()