iOS | 关于瀑布流附带悬停的简易实现

流式布局过去也玩很多种,今天来总结一下瀑布流,市面上应该是不那么流行了,不过无奈产品经理喜欢呀~


自定义布局

  • 其实需要使用到UICollectionViewLayout
    a、其决定UICollectionView如何将单元格显示

  • 实现流程
    1、 - (void)prepareLayout; 运算所有单元格位置
    2、 - (CGSize)collectionViewContentSize; 返回运算后视图的总大小
    3、 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect; 返回运算后的单元格布局属性(包含悬停的实现部分)
    4、 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath; 单元格进行布局时,返回的是要获取的布局属性
    5、 (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath; 同上,不同在于,非单元格、是头尾视图
    6、 - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath; 同上,是装饰视图,若没有不需要重载
    7、 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds; 当边界发生变化时,决定是否刷新

  • ok,流程介绍完毕,可以开始有作为了~


悬停关键点

  • 在于流程3中,保持y坐标对齐顶部
CGFloat headerHeight = CGRectGetHeight(attriture.frame);
CGRect frame = attriture.frame;
frame.origin.y = MIN(MAX(self.collectionView.contentOffset.y, CGRectGetMinY(itemAttribute.frame)-headerHeight-contentInsetOfSection.top),
                      CGRectGetMinY(itemAttribute.frame)+[_heightOfSections[section] floatValue]);
attriture.frame = frame;
attriture.zIndex = (NSIntegerMax/2)+section;
  • 在于流程7中,需要刷新视图,保证对齐
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    if (_sectionHeadersPinToVisibleBounds) {
        return YES;
    }
    return [super shouldInvalidateLayoutForBoundsChange:newBounds];
}

预览图

玉兰图

也可以下载项目查看~
# [WaterHoverLayout]

你可能感兴趣的:(iOS | 关于瀑布流附带悬停的简易实现)