UICollectionView中只有一个粘性标头

时间:2014-05-06 15:43:06

标签: ios objective-c uicollectionview

我正在尝试在UICollectionView中实现单个粘性标头。

我的粘性标题行为与您可以看到的常见标题略有不同,例如在UITableView。我在集合视图中有3个标题,我只想让其中一个标记为粘性,并在滚动内容时粘贴到顶部。

我的代码工作得很好。但是,当我向下滚动时,粘性标题会在某个时刻突然消失。向后滚动会使标题再次出现。我究竟做错了什么?

我附加了自定义布局的实现。它是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

2 个答案:

答案 0 :(得分:6)

我对此并不是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];
}

答案 1 :(得分:0)

Swift 5的答案

df <- structure(list(Name = structure(c(4L, 5L, 3L, 1L, 2L), .Label = c("m.7510T>C",
"NC_000023.11:g.(134493178_134493182)_(134501172_134501176)del", 
"NC_012920.1:m.7445A>G", "NG_012236.2:g.11027del", 
"NM_018077.3(RBM28):c.1052T>C(p.Leu351Pro)"
), class = "factor"), ClinicalSignificance = structure(c(1L, 
1L, 1L, 1L, 1L), .Label = "Pathogenic", class = "factor")), class = 
"data.frame", row.names = c("1", "2", "3", "4", "5"))

感谢@BrendanCain