使用UICollectionViewController
和我自己的UICollectionViewLayout
子类,我将一个显示Gannt样式时间图的视图放在一起。使用该框架来完成乐队非常容易。
我不清楚如何设计提供时间背景的支持视图。我在Inkscape中勾画了一个例子:
黑色矩形轮廓是当前用户可能滚动到的位置的示例。
所以,我得到了如何做粉色/橙色/黄色的乐队。我不太清楚如何实现的是背景条纹和时间标签。
我开始使用的一个选项是创建自定义UIView
子类并将其设置为backgroundView
的{{1}}属性。执行collectionView
绘制垂直条纹很容易。
更难的部分是让时间标签始终显示在当前滚动区域的顶部/底部,而不是显示在backgroundView的边缘。有没有办法弄清楚我的背景视图的当前可见区域是什么,而不是drawRect:
哪个是“完整”视图?
或者我应该以某种方式使用frame/bounds
和UICollectionView
的装饰功能。似乎不适合我在那里看到的API,但这是我的第一个UICollectionViewLayout
,所以也许我错了?
更新
自从原帖以来,我已经学到了两件事,这让我比以前更加困惑:
此属性中的视图(如果有)位于所有的视图下方 其他内容和大小自动填充整个范围 集合视图。
它们基本上是指设备的屏幕,而不是视图的实际范围。我发现在日志记录中,无论滚动,UICollectionView
和bounds\frame
参数始终都是屏幕的大小。
drawRect:
参数。我的想法是,我会使layoutAttributesForElementsInRect:
符合传入的论点。不幸的是,这个矩形似乎经常比可视区域大。我假设他们在可见区域的边缘之外做了一些缓存。答案 0 :(得分:2)
这就是我最终做的事情。我实际上使用装饰视图结束了(ab?)。这就是我做的方式,我对结果非常满意:
我添加了一个TimeBarsView
类,作为UICollectionReusableView
的子类:
@interface TimeBarsView : UICollectionReusableView
@property (assign, nonatomic) NSInteger offset; // horizontal scroll offset
@end
我使用offset
属性绘制背景视图,就好像它在drawRect:
方法中滚动到该位置一样。把它粘在一起的那块是:
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
[super applyLayoutAttributes: layoutAttributes];
self.offset = layoutAttributes.indexPath.item;
}
这里的诀窍是我使用背景路径的IndexPath
来传达其滚动位置。
在我的UIControllerViewLayout
子类中,我实现了以下方法:
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
来自initWithCoder
和init
:
- (void)registerTimeBars {
[self registerClass:[TimeBarsView class] forDecorationViewOfKind:@"TimeBars"];
}
通常的layoutAttributesForElementsInRect:
方法,前言如下:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *inRect = [NSMutableArray array];
[inRect addObject:
[self
layoutAttributesForDecorationViewOfKind:@"TimeBars" // link to the TimeBars
atIndexPath: [NSIndexPath
indexPathForItem:self.collectionView.contentOffset.x // use the current scroll x value as the indexPath
inSection:0]]];
... // other layouts for the normal item views like usual
return inRect;
}
最后
- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:decorationViewKind withIndexPath:indexPath];
CGPoint offset = self.collectionView.contentOffset;
CGSize size = self.collectionView.bounds.size;
// align current frame so it matches the current scroll box
layoutAttributes.frame = CGRectMake(offset.x, offset.y, size.width, size.height);
layoutAttributes.zIndex = -1; // make sure it's below other views
return layoutAttributes;
}
答案 1 :(得分:1)
我应该以某种方式使用装饰功能......?
不,这些相当于UITableView中的页眉/页脚。他们不会在后台工作。
老实说,我觉得你过于复杂了。我只想制作两个UICollectionViews - 一个用于黄色/橙色/粉色条形图,另一个用于时间条形图。禁用底部集合视图上的用户交互。在scrollViewDidScroll:
委托回调中,设置底部集合视图的内容偏移量以匹配顶部集合视图的内容偏移量。然后底部的一个将与顶部的一个滚动,它们将看起来像一个一样。