Only one sticky title in a UICollectionView

I am trying to implement one sticky title in UICollectionView.

My sticky-heading behavior is slightly different than usual, which you can see, for example. c UITableView. I have 3 headers in the collection view and I want only one of them to be sticky and stick to the top when scrolling through the contents.

My code works very well. However, when I scroll down, the sticky title disappears suddenly at some point. When scrolling back, the title appears again. What am I doing wrong?

I am adding an implementation of my custom layout. This is a subclass UICollectionViewFlowLayout.

@implementation CustomFlowLayout


- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *attributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
    CGPoint const contentOffset = self.collectionView.contentOffset;

    for (UICollectionViewLayoutAttributes *layoutAttributes in attributes)
    {
        // Adjust the sticky header frame.
        if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader] &&
            layoutAttributes.indexPath.section == SectionWithStickyHeadeIndex)
        {
            NSInteger numberOfItemsInSection = [self.collectionView numberOfItemsInSection:SectionWithStickyHeadeIndex];
            NSIndexPath *firstObjectIndexPath = [NSIndexPath indexPathForItem:0
                                                                    inSection:SectionWithStickyHeadeIndex];
            UICollectionViewLayoutAttributes *firstObjectAttrs;

            if (numberOfItemsInSection > 0)
            {
                firstObjectAttrs = [self layoutAttributesForItemAtIndexPath:firstObjectIndexPath];
            }
            else
            {
                firstObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                                                        atIndexPath:firstObjectIndexPath];
            }

            CGPoint origin = layoutAttributes.frame.origin;

            // Adjust the header origin so it sticks to the top.
            origin.y = MAX(contentOffset.y + self.collectionView.contentInset.top,
                           CGRectGetMinY(firstObjectAttrs.frame) - CGRectGetHeight(layoutAttributes.frame));

            layoutAttributes.zIndex = CGFLOAT_MAX;
            layoutAttributes.frame = (CGRect)
            {
                .origin = origin,
                .size = layoutAttributes.frame.size
            };

            break;
        }
    }

    return attributes;
}


- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound
{
    return YES;
}


@end
+4
1

100%, , , rect. , attributes, for, "" .

for, attributes, :

NSIndexPath *stickyHeaderIndexPath = [NSIndexPath indexPathForItem:0 inSection:SectionWithStickyHeaderIndex];
UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                                                                          atIndexPath:stickyHeaderIndexPath];
if (![attributes containsObject:layoutAttributes])
{
    [attributes addObject:layoutAttributes];
}
+6

Source: https://habr.com/ru/post/1539464/


All Articles