zoukankan      html  css  js  c++  java
  • 自定义流水布局(UICollectionViewFlowLayout的基本使用)

    最终显示的效果图

    思路:

    1、UICollection的基本设置,并且创建一个继承自UICollectionViewFlowLayout的类。(不能是UICollectionViewLayout,否则全部都需要自定义)

    2、在UICollectionViewFlowLayout类中完成四步

      - 1)重写prepareLayout方法进行基本的布局(cell在最左面的时候是在正中间),不能在init中布局,因为设置collectionView尺寸是在viewDidLoad中,而init在它之前调用,获得的collectionView的尺寸是空的

      - 2)重写shouldInvalidateLayoutForBoundsChange,当collectionView的显示范围发生改变的时候,让其内部重新布局(即让cell滚动起来)

      - 3)重写layoutAttributesForElementsInRect方法,让cell在左右滑动的时候,尺寸放大或缩小

      - 4)重写targetContentOffsetForProposedContentOffset方法,让最接近中心的cell在停在正中央。

    代码如下:

    viewContorller中:

     1 #import "ViewController.h"
     2 #import "ZWLineLayout.h"
     3 @interface ViewController () <UICollectionViewDataSource>
     4 @end
     5 @implementation ViewController
     6 static  NSString *ZWCellID = @"cell";
     7 - (void)viewDidLoad {
     8     [super viewDidLoad];
     9     //若为UICollectionViewLayout,itemSize和scrollDirection都需要自己写,下面的类继承自UICollectionViewLayout
    10     ZWLineLayout *layout = [[ZWLineLayout alloc] init];
    11     layout.itemSize = CGSizeMake(160, 160);
    12     CGRect rect = CGRectMake(0, 100, self.view.frame.size.width, self.view.frame.size.width * 0.6);
    13     UICollectionView *collection = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:layout];
    14     collection.dataSource = self;
    15     collection.backgroundColor = [UIColor greenColor];
    16     [self.view addSubview:collection];
    17     [collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:ZWCellID];
    18 }
    19 
    20 #pragma mark - 数据源方法
    21 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    22 {
    23     return 10;
    24 }
    25 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    26 {
    27     UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ZWCellID forIndexPath:indexPath];
    28     cell.backgroundColor = [UIColor orangeColor];
    29     return cell;
    30 }

    ZWLineLayout.m中

     1 #import "ZWLineLayout.h"
     2 
     3 @implementation ZWLineLayout
     4 
     5 /**
     6  * 用来做布局的初始化操作(不建议在init方法中进行布局的初始化操作)
     7  */
     8 - (void)prepareLayout
     9 {
    10     [super prepareLayout];
    11     //水平滚动
    12     self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    13     
    14     //
    15     CGFloat margin = (self.collectionView.frame.size.width - self.itemSize.width) / 2;
    16     self.collectionView.contentInset = UIEdgeInsetsMake(0, margin, 0, margin);
    17 }
    18 
    19 /**
    20  * 当collectionView的显示范围发生改变的时候,是否需要重新刷新布局
    21  * 一旦重新刷新布局,就会重新调用下面的方法:
    22  * 1.prepareLayout
    23  * 2.layoutAttributesForElementsInRect:方法
    24  */
    25 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
    26 {
    27     return YES;
    28 }
    29 
    30 
    31 /**
    32  * 这个方法的返回值是一个数组(数组里面存放着rect范围内所有元素的布局属性)
    33  * 这个方法的返回值决定了rect范围内所有元素的排布(frame)
    34  */
    35 //需要在viewController中使用上ZWLineLayout这个类后才能重写这个方法!!
    36 - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
    37 {
    38     //让父类布局好样式
    39     NSArray *arr = [super layoutAttributesForElementsInRect:rect];
    40     //计算出collectionView的中心的位置
    41     CGFloat ceterX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;
    42     /**
    43      * 1.一个cell对应一个UICollectionViewLayoutAttributes对象
    44      * 2.UICollectionViewLayoutAttributes对象决定了cell的frame
    45      */
    46     for (UICollectionViewLayoutAttributes *attributes in arr) {
    47         //cell的中心点距离collectionView的中心点的距离,注意ABS()表示绝对值
    48         CGFloat delta = ABS(attributes.center.x - ceterX);
    49         //设置缩放比例
    50         CGFloat scale = 1.1 - delta / self.collectionView.frame.size.width;
    51         //设置cell滚动时候缩放的比例
    52         attributes.transform = CGAffineTransformMakeScale(scale, scale);
    53     }
    54     
    55     return arr;
    56 }
    57 
    58 /**
    59  * 这个方法的返回值,就决定了collectionView停止滚动时的偏移量
    60  */
    61 - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
    62 {
    63     // 计算出最终显示的矩形框
    64     CGRect rect;
    65     rect.origin.y = 0;
    66     rect.origin.x = proposedContentOffset.x;
    67     rect.size = self.collectionView.frame.size;
    68     
    69     //获得super已经计算好的布局的属性
    70     NSArray *arr = [super layoutAttributesForElementsInRect:rect];
    71     
    72     //计算collectionView最中心点的x值
    73     CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
    74     
    75     CGFloat minDelta = MAXFLOAT;
    76     for (UICollectionViewLayoutAttributes *attrs in arr) {
    77         if (ABS(minDelta) > ABS(attrs.center.x - centerX)) {
    78             minDelta = attrs.center.x - centerX;
    79         }
    80     }
    81     proposedContentOffset.x += minDelta;
    82     return proposedContentOffset;
    83 }
    84 @end
  • 相关阅读:
    托付和事件的使用
    在使用supervisord 管理tomcat时遇到的小问题
    无法安装vmware tools的解决方PLEASE WAIT! VMware Tools is currently being installed on your system. Dependin
    (转)Openlayers 2.X加载高德地图
    (转)openlayers实现在线编辑
    (转) Arcgis for js加载百度地图
    (转)Arcgis for js加载天地图
    (转) 基于Arcgis for Js的web GIS数据在线采集简介
    (转) Arcgis for js之WKT和GEOMETRY的相互转换
    (转)Arcgis for Js之Graphiclayer扩展详解
  • 原文地址:https://www.cnblogs.com/hissia/p/5723629.html
Copyright © 2011-2022 走看看