iOS开发UI篇--使用UICollectionView实现一个列表头部拉伸效果的案例

一、案例演示

本案例Demo演示的是列表头部具有拉伸的效果,具有良好的用户体验。
当列表的offsetY小于0的时候,顶部的图片会跟随手势的下拉将头部的宽高进行相应地缩放。如下图所示:

《iOS开发UI篇--使用UICollectionView实现一个列表头部拉伸效果的案例》 1.gif

二、知识储备

2.1、自定义UICollectionViewFlowLayout

自定义UICollectionViewFlowLayout就是UICollectionView功能强大的精髓所在,它负责了将各个Cell、Supplementary View和Decoration Views进行组织和管理,可以高度定制内容的展现。

2.2、layoutAttributesForElementsInRect:方法

这是UICollectionViewFlowLayout布局类中最重要的方法了,同时可能也是最容易让人迷惑的方法。collection view调用这个方法并传递一个自身坐标系统中的矩形过去。这个矩形代表了这个视图的可见矩形区域(也就是它的bounds),你需要准备好处理传给你的任何矩形。

你的实现必须返回一个包含UICollectionViewLayoutAttributes对象的数组,为每一个cell包含这样的一个对象,supplementary view或decoration view在矩形区域内是可见的。UICollectionViewLayoutAttributes类包含了collection view内item的所有相关布局属性。默认情况下,这个类包含frame,center,size,transform3D,alpha,zIndex属性(properties),和hidden特性(attributes)。如果你的布局想要控制其他视图的属性(比如,背景颜色),你可以建一个UICollectionViewLayoutAttributes的子类,然后加上你自己的属性。

布局属性对象通过indexPath属性和他们对应的cell,supplementary view或者decoration view关联在一起。collection view为所有items从布局对象中请求到布局属性后,它将会实例化所有视图,并将对应的属性应用到每个视图上去。

注意!这个方法涉及到所有类型的视图,也就是cell,supplementary views和decoration views。一个幼稚的实现可能会选择忽略传入的矩形,并且为collection view中的所有视图返回布局属性。在原型设计和开发布局阶段,这是一个有效的方法。但是,这将对性能产生非常坏的影响,特别是可见cell远少于所有cell数量的时候,collection view和布局对象将会为那些不可见的视图做额外不必要的工作。

2.3、- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;

当collection view的bounds改变时,布局需要告诉collection view是否需要重新计算布局。

三、关键代码分析

自定义UICollectionViewFlowLayout的实现

#import "StretchyHeaderCollectionViewLayout.h"

@implementation StretchyHeaderCollectionViewLayout

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

- (UICollectionViewScrollDirection)scrollDirection{
    return UICollectionViewScrollDirectionVertical;
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    UICollectionView *collectionView = [self collectionView];
    CGPoint offset = [collectionView contentOffset];

    NSArray *attributes = [super layoutAttributesForElementsInRect:rect];

    if (offset.y<0) {
        CGFloat deltaY = fabs(offset.y);
        for (UICollectionViewLayoutAttributes *attrs in attributes ) {
            NSString *kind = [attrs representedElementKind];
            if (kind == UICollectionElementKindSectionHeader) {
                CGSize headerSize = [self headerReferenceSize];
                CGRect headRect = [attrs frame];
                headRect.size.height = headerSize.height+deltaY;
                headRect.size.width = headerSize.width +deltaY;
                headRect.origin.y = headRect.origin.y - deltaY;
                headRect.origin.x = headRect.origin.x - deltaY/2;
                [attrs setFrame:headRect];
                break;
            }
        }

    }

    return attributes;
}
@end

四、Demo下载地址

Demo下载地址:这是一个我的iOS交流群:937194184,群文件自行下载,不管你是小白还是大牛热烈欢迎进群 ,分享面试经验,讨论技术, 大家一起交流学习成长!希望帮助开发者少走弯路。——点击:加入

如果觉得对你还有些用,就关注小编+喜欢这一篇文章。你的支持是我继续的动力。

下篇文章预告:使用UICollectionView实现一个倾斜列表效果

文章来源于网络,如有侵权,请联系小编删除。

    原文作者:扒皮狼
    原文地址: https://www.jianshu.com/p/5ea6bde73af7
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞