17

UICollectionView補足ビューをヘッダーとしてmy に追加しようとしています。動作させるのに問題があります。

カスタムを使用して、フレームよりも常に少なくとも 1 ピクセル大きいUICollectionViewFlowLayouta を返し(スクロールした場合にのみ機能し、設定が直接何もしない a を使用しています)、オンにして変更します。contentSizeUIFreshControlUICollectionViewcollectionView.contentSizeinvalidateLayoutsectionInsertitemSize

-(void)setSectionInset:(UIEdgeInsets)sectionInset {
    if (UIEdgeInsetsEqualToEdgeInsets(super.sectionInset, sectionInset)) {
        return;
    }

    super.sectionInset = sectionInset;

    [self invalidateLayout];

}

-(void) setItemSize:(CGSize)itemSize {
    if (CGSizeEqualToSize(super.itemSize, itemSize)) {
        return;
    }

    super.itemSize = itemSize;

    [self invalidateLayout];
}

- (CGSize)collectionViewContentSize
{
    CGFloat height = [super collectionViewContentSize].height;

    // Always returns a contentSize larger then frame so it can scroll and UIRefreshControl will work
    if (height < self.collectionView.bounds.size.height) {
        height = self.collectionView.bounds.size.height + 1;
    }

    return CGSizeMake([super collectionViewContentSize].width, height);
}

UICollectionReusableViewだけのクラスを作成UIViewしましたUILabel

@implementation CollectionHeaderView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"CollectionHeaderView" owner:self options:nil];

        if ([arrayOfViews count] < 1) {
            return nil;
        }

        if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
            return nil;
        }

        self = [arrayOfViews objectAtIndex:0];

        self.headerLabel.text = @"This is a header. There are many like it.";
        self.backgroundColor = [UIColor yellowColor];


    }
    return self;
}

それを実装しようとしています:

DatasetLayout *collectionViewFlowLayout = [[DatasetLayout alloc] init];
collectionViewFlowLayout.itemSize = CGSizeMake(360, 160);
collectionViewFlowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
collectionViewFlowLayout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
collectionViewFlowLayout.minimumInteritemSpacing = 16;
collectionViewFlowLayout.minimumLineSpacing = 16;
collectionViewFlowLayout.headerReferenceSize = CGSizeMake(0, 100);

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewFlowLayout];
collectionView.translatesAutoresizingMaskIntoConstraints = FALSE;
collectionView.backgroundColor = [UIColor yellowColor];
collectionView.delegate = self;
collectionView.dataSource = self;

クラスを登録します:

[self.collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];

デリゲートを実装します。

-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {

    CollectionHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView" forIndexPath:indexPath];

    headerView.headerLabel.text = @"Blarg!";

    return headerView;
}

この線

collectionViewFlowLayout.headerReferenceSize = CGSizeMake(0, 100);

エラーが発生します:

*** Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:], /SourceCache/UIKit_Sim/UIKit-2380.17/UICollectionView.m:1150
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView dataSource is not set'

コメントアウトすると実行されますが、ヘッダーはありません。

私が間違っていること、または実装していないことは何ですか?

4

10 に答える 10

7

コードをクリーンアップし、IB で作成した UICollectionView を削除し、すべてコードで作成しました。もう一度実行したところ、別のエラーが発生し、IB でデリゲートまたはデータソースを設定していないことに気付きました。やった:

self.collectionView.delegate = self;
self.collectionView.datasource = self;

しかし、それだけでは十分ではなかったに違いありません。

したがって、UICollectionView を IB で作成し、デリゲート/データソースを IB で設定するのではなく、コードで設定します。

[self.view bringSubviewToFront:self.collectionView];
self.collectionView.collectionViewLayout = collectionViewFlowLayout;
self.collectionView.backgroundColor = [UIColor orangeColor];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;

[self.collectionView registerClass:[DatasetCell class] forCellWithReuseIdentifier:@"cvCell"];

[self.collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];

が問題でした。UICollectionView をすべてコードで作成するように作り直しました。

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewFlowLayout];
collectionView.translatesAutoresizingMaskIntoConstraints = FALSE;
collectionView.backgroundColor = [UIColor yellowColor];
collectionView.delegate = self;
collectionView.dataSource = self;

[collectionView registerClass:[DatasetCell class] forCellWithReuseIdentifier:@"cvCell"];

[collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];

[self.view addSubview:collectionView];

self.collectionView = collectionView;

そして、私は別のエラーが発生します:

*** Assertion failure in -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2380.17/UICollectionView.m:2249
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindSectionHeader with identifier CollectionHeaderView - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

私は理解しようとします。

編集:

それを理解した、私はヘッダーを間違って登録していました:

[collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];

切り替え:

UINib *headerNib = [UINib nibWithNibName:@"CollectionHeaderView" bundle:nil];

[collectionView registerNib:headerNib forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];

そしてすべてが機能します。ただし、どのように機能しなかったかは完全にregisterClass:はわかりません。

于 2013-03-05T18:06:03.270 に答える
1

エラーメッセージを見ると、データソースが設定されていないことがわかります。これで修正されるはずです:

self.collectionView.dataSource = self;

ビューコントローラがデータソースプロトコルを実装していることを確認してください。

YourViewController : UIViewController<UICollectionViewDataSource>

于 2013-03-05T17:50:11.423 に答える
1

この厄介なエラーも発生しました:

*** Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes:], /SourceCache/UIKit/UIKit-3347.44/UICollectionView.m:1400
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView dataSource is not set'

そして、私は何人かの人々がこのエラーを解決することを見つけました

- (void)dealloc {
    self.collectionView = nil;
}

または迅速に:

deinit {
    collectionView = nil
}

ただし、どちらも私のクラッシュを解決しませんでした。いくつか試してみたところ、次の「ハック」でこの厄介なバグが解決されました。

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    if collectionView.dataSource != nil {
        return someHeaderSize
    } else {
        return CGSizeZero
    }
}
于 2015-05-28T14:51:55.910 に答える
0

同じエラーが発生し続けました。collectionView に CustomHeaderView を設定しました。Collection Reusable View のクラスを CustomHeaderView に設定し、識別子を設定しました。なぜこれが失敗したのかを理解しようとしています。

キャッチされない例外 'NSInternalInconsistencyException' が原因でアプリを終了しています。理由: '種類のビューをデキューできませんでした: 識別子 SectionHeader を持つ UICollectionElementKindSectionFooter - 識別子のペン先またはクラスを登録するか、ストーリーボードのプロトタイプ セルを接続する必要があります'

ログを注意深く読む必要があります...教訓。

'種類のビューをデキューできませんでした: UICollectionElementKindSectionFooter

その理由は、ストーリーボードで - collectionView Identity Inspector で、アクセサリ: セクション ヘッダーとセクション フッターの両方をチェックしたためです。セクションヘッダーだけが必要でした。フッターのチェックを外すだけです...ビルドして実行してください..BOOM!

于 2016-01-02T20:34:46.017 に答える
0

これを試して :

self.collectionView?.dataSource = nil
self.collectionView = nil

それは私のために働いた;)

于 2015-10-08T13:20:15.053 に答える