How to make sticky headers in UICollectionView on iOS7?

后端 未结 1 1907
再見小時候
再見小時候 2021-02-11 09:55

I\'m using this solution to make sticky headers in collection view and it works well on iOS6. But in iOS7 if the \"Extend edges under top bars\" option is checked then the heade

相关标签:
1条回答
  • 2021-02-11 10:52

    Here is my full solution. Just add the following to your FlowLayout class:

    #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;
    }
    
    0 讨论(0)
提交回复
热议问题