我正在使用这个解决方案在集合视图中制作粘性标题,它在 iOS6 上运行良好。但是在 iOS7 中,如果选中了“在顶部栏下延伸边缘”选项,则标题会粘在视图的原点上,然后位于导航栏的后面。
所以现在我禁用了该选项,但我真的很想调整该解决方案以使其在边缘扩展时工作(以便在内容滚动到导航栏后面时具有良好的模糊效果)。
有人可以帮我吗?或者是否有人有任何其他建议来实现相同的目标?
我正在使用这个解决方案在集合视图中制作粘性标题,它在 iOS6 上运行良好。但是在 iOS7 中,如果选中了“在顶部栏下延伸边缘”选项,则标题会粘在视图的原点上,然后位于导航栏的后面。
所以现在我禁用了该选项,但我真的很想调整该解决方案以使其在边缘扩展时工作(以便在内容滚动到导航栏后面时具有良好的模糊效果)。
有人可以帮我吗?或者是否有人有任何其他建议来实现相同的目标?
这是我的完整解决方案。只需将以下内容添加到您的 FlowLayout 类中:
#pragma mark STICKY HEADERS CODE BELOW
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet];
for (NSUInteger idx=0; idx<[answer count]; idx++) {
UICollectionViewLayoutAttributes *layoutAttributes = answer[idx];
if (layoutAttributes.representedElementCategory == UICollectionElementCategoryCell || layoutAttributes.representedElementCategory == UICollectionElementCategorySupplementaryView) {
[missingSections addIndex:(NSUInteger) layoutAttributes.indexPath.section]; // remember that we need to layout header for this section
}
if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
[answer removeObjectAtIndex:idx]; // remove layout of header done by our super, we will do it right later
idx--;
}
}
// layout all headers needed for the rect using self code
[missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
if (layoutAttributes) {
[answer addObject:layoutAttributes];
}
}];
return answer;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionView * const cv = self.collectionView;
CGFloat topOffset = 0;
if ([self.collectionView.dataSource isKindOfClass:[UIViewController class]]) {
UIViewController *collectionViewParentViewController = (UIViewController *)self.collectionView.dataSource;
topOffset = collectionViewParentViewController.topLayoutGuide.length;
}
CGPoint const contentOffset = CGPointMake(cv.contentOffset.x, cv.contentOffset.y + topOffset);
CGPoint nextHeaderOrigin = CGPointMake(INFINITY, INFINITY);
if (indexPath.section+1 < [cv numberOfSections]) {
UICollectionViewLayoutAttributes *nextHeaderAttributes = [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:[NSIndexPath indexPathForItem:0 inSection:indexPath.section+1]];
nextHeaderOrigin = nextHeaderAttributes.frame.origin;
}
CGRect frame = attributes.frame;
if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
frame.origin.y = MIN(MAX(contentOffset.y, frame.origin.y), nextHeaderOrigin.y - CGRectGetHeight(frame));
}
else {
frame.origin.x = MIN(MAX(contentOffset.x, frame.origin.x), nextHeaderOrigin.x - CGRectGetWidth(frame));
}
attributes.zIndex = 1024;
attributes.frame = frame;
}
return attributes;
}
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
return attributes;
}
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
return attributes;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound {
return YES;
}