8

我創建了自定義UICollectionViewLayout,並將其放入故事板中的Collection View Controller中。我沒有在顯示物品/單元時遇到太多問題。我的問題是viewForSupplementaryElementOfKind沒有被調用。我似乎無法確定爲什麼會這樣。我試圖回到默認佈局,它確實調用它,但我需要我的自定義UICollectionViewLayout。我已經離開NSLogs檢查和viewForSupplementaryElementOfKind沒有被調用。viewForSupplementaryElementOfKind未在自定義UICollectionViewLayout上調用

這裏是我的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。我嘗試實現layoutAttributesForItemAtIndexPath,因爲我有layoutAttributesForSupplementaryViewOfKind。我也嘗試使用像75和320這樣的固定數字來檢查是否生成頭文件。你看到的代表只是爲了獲得一個視圖的高度。 (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath是不是被稱爲。

這裏有一些我已經看過並嘗試過:stackoverflow,但你可以從我已包含的註釋代碼中看到。它仍然沒有工作。

感謝您的幫助。

+0

哎,也沒找到答案?因爲我有和你一樣的問題 – Ali

+0

耶還沒有找到一個。我正在閱讀一個名爲CHTCollectionViewWaterfallLayout的圖書館,以及他們迄今爲止做到了什麼,但我還沒有找到答案。 – Revin

回答

5

我也有這個問題,我的解決辦法是簡單地增加對部分屬性在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]; 
4

添加頁眉節的默認大小:

collectionViewLayout.headerReferenceSize = CGSize(width, height) 

默認大小值(0,0)。這就是爲什麼標題不顯示。

OR

還有另一種方式是,實施UICollectionView的委託方法:

collectionView(_:layout:referenceSizeForFooterInSection:) 
+0

這應該是被接受的答案。 – shoujs

相關問題