I created a custom UICollectionViewLayout and I put it in my collection controller in a storyboard. I had no problems displaying elements / cells. My problem is that viewForSupplementaryElementOfKind is not called. I canβt understand why this is so. I tried to return to the default layout, and it is called, but I need my custom UICollectionViewLayout. I left NSLogs to check and viewForSupplementaryElementOfKind is not called.
Here is my 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)]; }
Now here is my 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 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;
}
As you can see in MyFlowLayout, there are things I tried, but still it did not call viewForSupplementaryElementOfKind. I tried to implement layoutAttributesForItemAtIndexPath since I have layoutAttributesForSupplementaryViewOfKind. I also tried using fixed numbers like 75 and 320, which you see to check if the header will be generated. The delegate you see is just for getting the height of the view.
Since I gave the title enough space for viewing and left NSLogs around and (UICollectionReusableView *) collectionView: (UICollectionView *) collectionView viewForSupplementaryElementOfKind: (NSString *) kind atIndexPath: (NSIndexPath *) indexPath is not called.
Here are some of them that I looked through and tried: https://stackoverflow.com/a/167015/button/questions/414011/ ... , but as you can see from the comment I included. It still didn't work.
Thanks for the help.