8

Ich habe eine benutzerdefinierte UICollectionViewLayout erstellt und ich habe es in meinem Collection View Controller in das Storyboard. Ich habe nicht so viele Probleme beim Anzeigen der Gegenstände/Zellen bekommen. Mein Problem ist, dass der viewForSupplementaryElementOfKind nicht aufgerufen wird. Ich kann nicht darauf hinweisen, warum das so ist. Ich habe versucht, zum Standardlayout zurückzukehren und es ruft es dann aber ich brauche meine benutzerdefinierte UICollectionViewLayout. Ich habe NSLogs zu überprüfen und viewForSupplementaryElementOfKind wird nicht aufgerufen.viewForSupplementaryElementOfKind nicht auf benutzerdefinierte UICollectionViewLayout

Hier ist meine 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); 
} 

hier ist jetzt mein 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; 

}

Wie Sie in MyFlowLayout sehen können, gibt es Dinge, die ich habe versucht, aber es hat noch nicht ViewForSupplementaryElementOfKind aufgerufen. Ich habe versucht, layoutAttributesForItemAtIndexPath zu implementieren, da ich layoutAttributesForSupplementaryViewOfKind habe. Ich habe auch versucht, feste Zahlen wie die 75 und 320 zu verwenden, die Sie nur sehen, um zu überprüfen, ob der Header generiert würde. Der Delegat, den Sie sehen, dient nur dazu, die Höhe einer Ansicht zu erhalten.

Da ich den Header genügend Platz gegeben haben gesehen, und links NSLogs überall und doch (UICollectionReusableView *) Collection werden: (UICollectionView *) Collection viewForSupplementaryElementOfKind: (NSString *) Art atIndexPath: (NSIndexPath *) indexPath ist nicht gerufen werden.

Hier sind einige, die ich gesucht und ausprobiert habe: stackoverflow aber wie Sie aus dem kommentierten Code sehen können, die ich aufgenommen habe. Es hat immer noch nicht funktioniert.

Danke für die Hilfe.

+0

Hey, Sie haben nicht eine Antwort finden? weil ich das selbe Problem habe wie du – Ali

+0

hast ja noch keinen gefunden. Ich lese gerade eine Bibliothek namens CHTCollectionViewWaterfallLayout und wie sie es bisher gemacht haben habe ich die Antwort nicht gefunden. – Revin

Antwort

5

Ich hatte auch ein Problem mit diesem und meine Lösung war einfach Attribute für Abschnitt hinzufügen in 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

Fügen Sie die Standardgröße von Header-Bereich:

collectionViewLayout.headerReferenceSize = CGSize(width, height) 

Die Standardgröße Werte sind (0, 0). Deshalb wird Header nicht angezeigt.

OR

Es gibt auch eine andere Möglichkeit für sie, implementieren die delegierte Methode für UICollectionView:

collectionView(_:layout:referenceSizeForFooterInSection:) 
+0

Dies sollte die akzeptierte Antwort sein. – shoujs