web-dev-qa-db-ja.com

viewForSupplementaryElementOfKindがカスタムUICollectionViewLayoutで呼び出されていない

カスタムUICollectionViewLayoutを作成し、ストーリーボードのコレクションビューコントローラーに配置しました。アイテム/セルの表示に関してはそれほど問題はありませんでした。私の問題は、viewForSupplementaryElementOfKindが呼び出されていないことです。それがなぜなのか、正確に特定できないようです。デフォルトのレイアウトに戻ろうとしましたが、それが呼び出されますが、カスタムUICollectionViewLayoutが必要です。 NSLogsをチェックするために残しましたが、viewForSupplementaryElementOfKindが呼び出されていません。

これが私のMyCollectionViewController.mです

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
viewArray = [NSMutableArray array];

//setup the delegate for vertical flow layout
[(VerticalFlowLayout*)self.collectionViewLayout setDelegate:self];

//register the headers
[self.collectionView registerNib:[ButtonHeaderCollectionReusableView nib] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:[ButtonHeaderCollectionReusableView reusableID]];

//set the insets
[self.collectionView setContentInset:UIEdgeInsetsMake(23, 5, 10, 5)]; }

#pragma mark - CollectionView DataSource

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.cardsArray count];
}

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
NSLog(@"Number of Sections");

return 1;
}

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

NSLog(@"Making Card");

CardCell *card = [collectionView dequeueReusableCellWithReuseIdentifier:@"CardCell" forIndexPath:indexPath];

//    UILabel *cardLabel = [card viewWithTag:101];
//    [cardLabel setText:[textArray objectAtIndex:[indexPath row]]];

return card;
}

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

NSLog(@"Making Header");

UICollectionReusableView *reusableView = nil; /*[[UICollectionReusableView alloc] initWithFrame:CGRectMake(0, 0, 100, 75)];*/
//    [reusableView setBackgroundColor:[UIColor blackColor]];

if (kind == UICollectionElementKindSectionHeader) {
    ButtonHeaderCollectionReusableView *headerview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:[ButtonHeaderCollectionReusableView reusableID] forIndexPath:indexPath];

    return headerview;
}

//    if (kind == UICollectionElementKindSectionFooter) {
//        UICollectionReusableView *footerview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"FooterView" forIndexPath:indexPath];
//    }

return reusableView;
}

-(CGSize)collectionView:collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
return CGSizeMake(180.0f, 72.0f);
}

これが私のMyFlowLayout.mです

-(id)initWithCoder:(NSCoder *)aDecoder {
NSLog(@"Vertical Flow Layout init with coder");
if(self = [super initWithCoder:aDecoder]) {
    contentHeight = 0;
    cachedAttributes = [NSMutableArray array];
}

return self;
}

-(void)prepareLayout {
NSLog(@"Preparing Layout");
//    [super prepareLayout];

contentWidth = CGRectGetWidth(self.collectionView.bounds) - (self.collectionView.contentInset.left + self.collectionView.contentInset.right);

if([cachedAttributes count] == 0) {
    //compute for column width
    CGFloat columnWidth = contentWidth / NUMBER_OF_COLUMNS;
    NSMutableArray *xOffsets = [NSMutableArray array];
    for(int i = 0; i < NUMBER_OF_COLUMNS; i++) {
        [xOffsets addObject:[NSNumber numberWithFloat:(i * columnWidth)]];
    }

    //compute for height
    NSMutableArray *yOffsets = [NSMutableArray array];
    for(int i = 0; i < NUMBER_OF_COLUMNS; i++) {
        [yOffsets addObject:[NSNumber numberWithFloat:75]];
    }

    int column = 0;
    //loop through all the sections and items in the collectionview
    for(int i = 0; i < self.collectionView.numberOfSections; i++) {
        for(int j = 0; j < [self.collectionView numberOfItemsInSection:i]; j++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:j inSection:i];

            //time to do some frame calculation
            ///let's start with the width
            CGFloat width = columnWidth - CELL_PADDING * 2;
            ///then the height
            CGFloat viewHeight = [self.delegate getViewHeightWithCollectionView:self.collectionView indexPath:indexPath withWidth:width];
            CGFloat height = CELL_PADDING + viewHeight + /*textHeight +*/ CELL_PADDING;

            CGFloat xOffset = [[xOffsets objectAtIndex:column] floatValue];
            CGFloat yOffset = [[yOffsets objectAtIndex:column] floatValue];

            CGRect frame = CGRectMake(xOffset, yOffset, columnWidth, height);
            CGRect insetFrame = CGRectInset(frame, CELL_PADDING, CELL_PADDING);

            //now that computation is done we shall make the attributes
            UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
            [attributes setFrame:insetFrame];
            [cachedAttributes addObject:attributes];

            //time to increment the height and the column
            contentHeight = MAX(contentHeight, CGRectGetMaxY(frame));
            NSNumber *yOffSetColumn = [yOffsets objectAtIndex:column];
            yOffSetColumn = [NSNumber numberWithFloat:([yOffSetColumn floatValue] + height)];
            [yOffsets replaceObjectAtIndex:column withObject:yOffSetColumn];

            NSLog(@"Content Height: %f yOffSetColumn: %@ == %@", contentHeight, yOffSetColumn, [yOffsets objectAtIndex:column]);

            column = column >= (NUMBER_OF_COLUMNS - 1) ? 0 : ++column;
        }
    }
}
}

-(CGSize)collectionViewContentSize {
//    NSLog(@"Collection View Content Size");
return CGSizeMake(contentWidth, contentHeight + 75);
}

//called after preparelayout to determine which items are visible in the given rect
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray

<UICollectionViewLayoutAttributes *> *layoutAttributes = [NSMutableArray array];

NSInteger sectionsCount = [self.collectionView.dataSource numberOfSectionsInCollectionView:self.collectionView];

NSLog(@"Sections count: %ld", (long)sectionsCount);

for(int i = 0; i < sectionsCount; i++) {
    //for header
    UICollectionViewLayoutAttributes *headerAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:i]];
//        if(CGRectIntersectsRect(headerAttributes.frame, rect)) {
//            NSLog(@"Adding Section Attribute");
        [layoutAttributes addObject:headerAttributes];
//        }

    for (UICollectionViewLayoutAttributes *attributes in cachedAttributes) {
        if(CGRectIntersectsRect(attributes.frame, rect)) {
            [layoutAttributes addObject:attributes];
        }
    }

//        NSInteger itemsCount = [self.collectionView numberOfItemsInSection:i];
//        for(int j = 0; j < itemsCount; j++) {
//            UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:j inSection:i]];
//            if(CGRectIntersectsRect(attributes.frame, rect)) {
//                [layoutAttributes addObject:attributes];
//            }
//        }
    }


return layoutAttributes;
}

//-(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
//    NSLog(@"Layout Attributes For Item: %ld %ld", [indexPath row], [indexPath section]);
//    
//    UICollectionViewLayoutAttributes *attributes = [cachedAttributes objectAtIndex:[indexPath row]];
//    return attributes;
//}

-(UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath {

NSLog(@"Layout Attributes For Header: %@ %ld %ld", elementKind, [indexPath row], [indexPath section]);

UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
[attributes setFrame:CGRectMake(0, 0, contentWidth /*320*/, 75.0f)];

return attributes;

}

MyFlowLayoutでわかるように、私が試したことがいくつかありますが、それでもviewForSupplementaryElementOfKindを呼び出しませんでした。 layoutAttributesForSupplementaryViewOfKindがあるので、layoutAttributesForItemAtIndexPathを実装してみました。ヘッダーが生成されるかどうかを確認するために表示される75や320などの固定番号も使用してみました。あなたが見る代表者、それはただ眺めの高さを得るためです。

ヘッダーに表示するのに十分なスペースを指定し、NSLogを全体に残したので、(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPathが呼び出されていません。

これが私が見て試したいくつかです: stackoverflow しかし、あなたが私が含めたコメントされたコードからわかるように。それでも機能しませんでした。

助けてくれてありがとう。

11
Revin

私もこれに問題があり、私の解決策は単にprepareLayoutのセクションの属性を追加することでした

UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
attributes.frame = CGRectMake(0, 0, self.collectionView.frame.size.width, 100);
[cachedAttributes addObject:attributes];
9
I. Alex

ヘッダーセクションのデフォルトサイズを追加します。

collectionViewLayout.headerReferenceSize = CGSize(width, height)

デフォルトのサイズ値は(0、0)です。そのため、ヘッダーが表示されません。

OR

それには別の方法もあり、UICollectionViewのデリゲートメソッドを実装します。

collectionView(_:layout:referenceSizeForFooterInSection:)
8
Rocky