这就是我最终要做的。我实际上最终(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;
}