8

Utworzono niestandardowy UICollectionViewLayout i umieściłem go w moim sterowniku widoku kolekcji w serii ujęć. Nie miałem tak dużo problemów z wyświetlaniem elementów/komórek. Mój problem polega na tym, że viewForSupplementaryElementOfKind nie jest wywoływany. Nie mogę chyba powiedzieć, dlaczego tak jest. Próbowałem wrócić do domyślnego układu i to się nazywa, ale potrzebuję mojego niestandardowego UICollectionViewLayout. Zostawiłem NSLogs do sprawdzenia i viewForSupplementaryElementOfKind nie jest wywoływany.viewForSupplementaryElementOfNie jest wywoływane niestandardowo UICollectionViewLayout

Oto moja 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); 
} 

Teraz tutaj jest mój 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; 

}

Jak widać w MyFlowLayout, są rzeczy, próbowałem ale nadal nie wywoływał viewForSupplementaryElementOfKind. Próbowałem wdrażanie layoutAttributesForItemAtIndexPath, ponieważ mam layoutAttributesForSupplementaryViewOfKind. Próbowałem również używać stałych numerów, takich jak 75 i 320, które widzisz, aby sprawdzić, czy nagłówek zostanie wygenerowany. Delegat, którego widzisz, służy tylko do zdobycia wysokości widoku.

Od Dałem nagłówka wystarczająco dużo miejsca, aby być postrzegane i lewo NSLogs całego i jeszcze (UICollectionReusableView *) CollectionView: (UICollectionView *) CollectionView viewForSupplementaryElementOfKind: (NSString *) rodzaj atIndexPath: (NSIndexPath *) indexPath nie jest być nazwanym.

Oto niektóre, które sprawdziłem i wypróbowałem: stackoverflow, ale jak widać na podstawie skomentowanego kodu, który dodałem. Nadal nie działa.

Dzięki za pomoc.

+0

Hej, nie znaleźliśmy odpowiedzi? ponieważ mam ten sam problem co ty, – Ali

+0

tak, jeszcze go nie znalazłem. Czytam bibliotekę CHTCollectionViewWaterfallLayout i jak do tej pory nie znalazłem odpowiedzi. – Revin

Odpowiedz

5

Miałem też problem z tym i moje rozwiązanie było po prostu dodać atrybuty sekcji w 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

Dodaj domyślny rozmiar sekcji nagłówka:

wartości rozmiaru
collectionViewLayout.headerReferenceSize = CGSize(width, height) 

fabryczne są (0, 0). Właśnie dlatego nagłówek się nie wyświetla.

LUB

Istnieje również inny sposób na to, wdrożyć metodę Delegat UICollectionView:

collectionView(_:layout:referenceSizeForFooterInSection:) 
+0

To powinna być zaakceptowana odpowiedź. – shoujs