我正在尝试使用UICollectionView和自定义布局实现类似本机日历应用程序的时间轴视图。我是新手。
这是我的问题所在。
我正在使用装饰视图来实现这些背景网格线,并尝试使用补充视图来制作时间标签(靠近网格线),并且将使用Cell来制作事件但不是那么远。
但是在做这些事件之前,我发现当我运行它时,所有的补充视图都不起作用,无论我是否有单元格。我发现我的 collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法未被调用。
所以我想知道如何以及何时调用此方法?什么可能导致我的情况,它没有被调用?
实际上,制作具有补充视图的时间标签是否合适?我不确定它,因为即使没有事件(部分中没有单元格/项目),我确实需要它们可见。
这是我的代码:
查看控制器
- (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;
}
自定义布局
// in prepareLayout
NSMutableDictionary *timeHeaderAttributes = [NSMutableDictionary dictionary];
CGSize headerSize = [TodayTimelineTimeHeader defaultSize];
CGFloat headerOffsetY = (tileSize.height - headerSize.height) / 2;
for (NSInteger hour = 24; hour >= 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);
}
我尽量不在这里发布所有代码,因为这很多,但如果你需要了解其他人,请告诉我。
任何提示都表示赞赏!
松
答案 0 :(得分:2)
所以,这个问题解决了,原因是我的愚蠢错误,将这些视图的位置x设置在屏幕之外,并且由于没有调用该方法。没别了。
我通过在prepareLayout中注销每个视图的框架找到了这个原因,并发现x位置错误。我从视网膜设计中得到了这个位置......
我使用了补充视图,它没有任何问题。
我的教训:不用担心,冷静下来。这可以节省你的错误时间。