Note that there are some explanatory texts on larger screens.

plurals
  1. POWhen and how is collectionView:viewForSupplementaryElementOfKind:atIndexPath: called?
    primarykey
    data
    text
    <p>I'm trying to implement a native-Calendar-app-like timeline view with UICollectionView and custom layout. And I'm new to it.</p> <p>Here is where my problem come from.</p> <p>I'm using Decoration View to implement those background gridlines, and trying to use Supplementary View to make the time labels (near the gridlines), and will use Cell to make the events but not that far yet.</p> <p>But before doing the events, I found when I run it all the supplementary views are not working, no matter if I have cell or not. And I found my <strong>collectionView:viewForSupplementaryElementOfKind:atIndexPath: method is not called</strong>.</p> <p>So I'm wondering how and when this method is called? What could be leading to my situation that it's not called?</p> <p>Actually, is it good to make those time labels with supplementary view? I'm not sure about it since I do need them to be visible even when there's no event (no cell/item in section).</p> <p>Here is my code:</p> <p><strong>View Controller</strong></p> <pre><code>- (void)viewDidLoad { [super viewDidLoad]; self.collectionView.backgroundColor = [UIColor whiteColor]; [self.collectionView registerClass:TodayCellKindTask.class forCellWithReuseIdentifier:CellKindTaskIdentifier]; [self.collectionView registerClass:TodayTimelineTimeHeader.class forSupplementaryViewOfKind:TimelineKindTimeHeader withReuseIdentifier:TimelineTimeHeaderIdentifier]; [self.timelineViewLayout registerClass:TodayTimelineTileWhole.class forDecorationViewOfKind:TimelineKindTileWholeHour]; [self.timelineViewLayout registerClass:TodayTimelineTileHalf.class forDecorationViewOfKind:TimelineKindTileHalfHour]; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 5; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { TodayCellKindTask *cellTask = [collectionView dequeueReusableCellWithReuseIdentifier:CellKindTaskIdentifier forIndexPath:indexPath]; return cellTask; } - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { NSLog(@"viewForSupplementaryElementOfKind"); TodayTimelineTimeHeader *timeHeader = [self.collectionView dequeueReusableSupplementaryViewOfKind:TimelineKindTimeHeader withReuseIdentifier:TimelineTimeHeaderIdentifier forIndexPath:indexPath]; NSCalendar *calendar = [NSCalendar currentCalendar]; NSDate *today = [NSDate date]; NSDateComponents *comps = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:today]; [comps setHour:indexPath.item]; timeHeader.time = [calendar dateFromComponents:comps]; return timeHeader; } </code></pre> <p><strong>Custom Layout</strong></p> <pre><code>// in prepareLayout NSMutableDictionary *timeHeaderAttributes = [NSMutableDictionary dictionary]; CGSize headerSize = [TodayTimelineTimeHeader defaultSize]; CGFloat headerOffsetY = (tileSize.height - headerSize.height) / 2; for (NSInteger hour = 24; hour &gt;= 0; hour--) { NSIndexPath *timeHeaderIndexPath = [NSIndexPath indexPathForItem:hour inSection:0]; UICollectionViewLayoutAttributes *currentTimeHeaderAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:TimelineKindTimeHeader withIndexPath:timeHeaderIndexPath]; CGFloat headerPosY = hour * 2 * tileSize.height + headerOffsetY; currentTimeHeaderAttributes.frame = CGRectMake(TimeHeaderPosX, headerPosY, headerSize.width, headerSize.height); timeHeaderAttributes[timeHeaderIndexPath] = currentTimeHeaderAttributes; } self.timelineTileAttributes[TimelineKindTimeHeader] = timeHeaderAttributes; // layoutAttributesForSupplementaryViewOfKind - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { return self.timelineTileAttributes[kind][indexPath]; } // layoutAttributesForElementsInRect - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.timelineTileAttributes.count]; [self.timelineTileAttributes enumerateKeysAndObjectsUsingBlock:^(NSString *elementIdentifier, NSDictionary *elementsInfo, BOOL *stop) { [elementsInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath, UICollectionViewLayoutAttributes *attributes, BOOL *stop) { if (CGRectIntersectsRect(rect, attributes.frame)) { [allAttributes addObject:attributes]; } }]; }]; return allAttributes; } // collectionViewContentSize - (CGSize)collectionViewContentSize { CGSize tileSize = [TodayTimelineTileWhole defaultSize]; CGFloat contentHeight = tileSize.height * self.numberOfTiles; return CGSizeMake(tileSize.width, contentHeight); } </code></pre> <p>I tried not to post all the code here since that'd be a lot, but let me know if you need to know others.</p> <p>Any tip is appreciated!</p> <p>Pine</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload