美文网首页程序员iOS开发应用
iOS开发UI篇--使用UICollectionView实现一个

iOS开发UI篇--使用UICollectionView实现一个

作者: 扒皮狼 | 来源:发表于2018-11-23 12:06 被阅读8次

    一、案例演示

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

    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交流群:624212887,群文件自行下载,不管你是小白还是大牛热烈欢迎进群 ,分享面试经验,讨论技术, 大家一起交流学习成长!希望帮助开发者少走弯路。——点击:加入

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

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

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

    相关文章

      网友评论

      本文标题:iOS开发UI篇--使用UICollectionView实现一个

      本文链接:https://www.haomeiwen.com/subject/ebfjqqtx.html