zoukankan      html  css  js  c++  java
  • 9

    首先, 对于瀑布流的实现大体分为tableView和collectionView实现两种, 以collectionView实现最为简单. 本文对流行的实现方式进行改进, 减少依赖,增加更多代理方法,增加扩展性

     1 //
     2 //  AYWaterFlowLayout.h
     3 //  AY瀑布流
     4 //
     5 //  Created by Jasper on 16/1/25.
     6 //  Copyright © 2016年 Jasper. All rights reserved.
     7 //
     8 
     9 #import <UIKit/UIKit.h>
    10 
    11 @class AYWaterFlowLayout;
    12 
    13 @protocol AYWaterFlowLayoutDelegate <NSObject>
    14 @required
    15 - (CGFloat)waterflowLayout:(AYWaterFlowLayout *)waterflowLayout heightForItemAtIndex:(NSUInteger)index itemWidth:(CGFloat)itemWidth;
    16 
    17 @optional
    18 - (CGFloat)columnCountInWaterflowLayout:(AYWaterFlowLayout *)waterflowLayout;
    19 - (CGFloat)columnMarginInWaterflowLayout:(AYWaterFlowLayout *)waterflowLayout;
    20 - (CGFloat)rowMarginInWaterflowLayout:(AYWaterFlowLayout *)waterflowLayout;
    21 - (UIEdgeInsets)edgeInsetsInWaterflowLayout:(AYWaterFlowLayout *)waterflowLayout;
    22 @end
    23 
    24 
    25 @interface AYWaterFlowLayout : UICollectionViewLayout
    26 /** 代理 */
    27 @property (nonatomic, weak) id<AYWaterFlowLayoutDelegate> delegate;
    28 @end
      1 //
      2 //  AYWaterFlowLayout.m
      3 //  AY瀑布流
      4 //
      5 //  Created by Jasper on 16/1/25.
      6 //  Copyright © 2016年 Jasper. All rights reserved.
      7 //
      8 
      9 #import "AYWaterFlowLayout.h"
     10 
     11 
     12 /** 默认的列数 */
     13 static const NSInteger AYDefaultColumnCount = 3;
     14 /** 每一列之间的间距 */
     15 static const CGFloat AYDefaultColumnMargin = 10;
     16 /** 每一行之间的间距 */
     17 static const CGFloat AYDefaultRowMargin = 10;
     18 /** 边缘间距 */
     19 static const UIEdgeInsets AYDefaultEdgeInsets = {10, 10, 10, 10};
     20 
     21 
     22 
     23 
     24 
     25 @interface AYWaterFlowLayout ()
     26 
     27 /** 存放所有cell的布局属性 */
     28 @property (nonatomic, strong) NSMutableArray *attrsArray;
     29 /** 存放所有列的当前高度 */
     30 @property (nonatomic, strong) NSMutableArray *columnHeights;
     31 /** 内容的高度 */
     32 @property (nonatomic, assign) CGFloat contentHeight;
     33 
     34 
     35 - (CGFloat)rowMargin;
     36 - (CGFloat)columnMargin;
     37 - (NSInteger)columnCount;
     38 - (UIEdgeInsets)edgeInsets;
     39 
     40 @end
     41 
     42 
     43 @implementation AYWaterFlowLayout
     44 
     45 #pragma mark - 常见数据处理
     46 - (CGFloat)rowMargin
     47 {
     48     if ([self.delegate respondsToSelector:@selector(rowMarginInWaterflowLayout:)]) {
     49         return [self.delegate rowMarginInWaterflowLayout:self];
     50     } else {
     51         return AYDefaultRowMargin;
     52     }
     53 }
     54 
     55 - (CGFloat)columnMargin
     56 {
     57     if ([self.delegate respondsToSelector:@selector(columnMarginInWaterflowLayout:)]) {
     58         return [self.delegate columnMarginInWaterflowLayout:self];
     59     } else {
     60         return AYDefaultColumnMargin;
     61     }
     62 }
     63 
     64 - (NSInteger)columnCount
     65 {
     66     if ([self.delegate respondsToSelector:@selector(columnCountInWaterflowLayout:)]) {
     67         return [self.delegate columnCountInWaterflowLayout:self];
     68     } else {
     69         return AYDefaultColumnCount;
     70     }
     71 }
     72 
     73 - (UIEdgeInsets)edgeInsets
     74 {
     75     if ([self.delegate respondsToSelector:@selector(edgeInsetsInWaterflowLayout:)]) {
     76         return [self.delegate edgeInsetsInWaterflowLayout:self];
     77     } else {
     78         return AYDefaultEdgeInsets;
     79     }
     80 }
     81 
     82 #pragma mark - 懒加载
     83 - (NSMutableArray *)columnHeights
     84 {
     85     if (!_columnHeights) {
     86         _columnHeights = [NSMutableArray array];
     87     }
     88     return _columnHeights;
     89 }
     90 
     91 - (NSMutableArray *)attrsArray
     92 {
     93     if (!_attrsArray) {
     94         _attrsArray = [NSMutableArray array];
     95     }
     96     return _attrsArray;
     97 }
     98 
     99 /**
    100  * 初始化
    101  */
    102 - (void)prepareLayout
    103 {
    104     [super prepareLayout];
    105     
    106     self.contentHeight = 0;
    107     
    108     // 清除以前计算的所有高度
    109     [self.columnHeights removeAllObjects];
    110     for (NSInteger i = 0; i < self.columnCount; i++) {
    111         [self.columnHeights addObject:@(self.edgeInsets.top)];
    112     }
    113     
    114     // 清除之前所有的布局属性
    115     [self.attrsArray removeAllObjects];
    116     // 开始创建每一个cell对应的布局属性
    117     NSInteger count = [self.collectionView numberOfItemsInSection:0];
    118     for (NSInteger i = 0; i < count; i++) {
    119         // 创建位置
    120         NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
    121         // 获取indexPath位置cell对应的布局属性
    122         UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
    123         [self.attrsArray addObject:attrs];
    124     }
    125 }
    126 
    127 /**
    128  * 决定cell的排布
    129  */
    130 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    131 {
    132     return self.attrsArray;
    133 }
    134 
    135 /**
    136  * 返回indexPath位置cell对应的布局属性
    137  */
    138 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
    139 {
    140     // 创建布局属性
    141     UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    142     
    143     // collectionView的宽度
    144     CGFloat collectionViewW = self.collectionView.frame.size.width;
    145     
    146     // 设置布局属性的frame
    147     CGFloat w = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin) / self.columnCount;
    148     CGFloat h = [self.delegate waterflowLayout:self heightForItemAtIndex:indexPath.item itemWidth:w];
    149     
    150     // 找出高度最短的那一列
    151     NSInteger destColumn = 0;
    152     CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
    153     for (NSInteger i = 1; i < self.columnCount; i++) {
    154         // 取得第i列的高度
    155         CGFloat columnHeight = [self.columnHeights[i] doubleValue];
    156         
    157         if (minColumnHeight > columnHeight) {
    158             minColumnHeight = columnHeight;
    159             destColumn = i;
    160         }
    161     }
    162     
    163     CGFloat x = self.edgeInsets.left + destColumn * (w + self.columnMargin);
    164     CGFloat y = minColumnHeight;
    165     if (y != self.edgeInsets.top) {
    166         y += self.rowMargin;
    167     }
    168     attrs.frame = CGRectMake(x, y, w, h);
    169     
    170     // 更新最短那列的高度
    171     self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));
    172     
    173     // 记录内容的高度
    174     CGFloat columnHeight = [self.columnHeights[destColumn] doubleValue];
    175     if (self.contentHeight < columnHeight) {
    176         self.contentHeight = columnHeight;
    177     }
    178     return attrs;
    179 }
    180 
    181 - (CGSize)collectionViewContentSize
    182 {
    183     //    CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];
    184     //    for (NSInteger i = 1; i < self.columnCount; i++) {
    185     //        // 取得第i列的高度
    186     //        CGFloat columnHeight = [self.columnHeights[i] doubleValue];
    187     //
    188     //        if (maxColumnHeight < columnHeight) {
    189     //            maxColumnHeight = columnHeight;
    190     //        }
    191     //    }
    192     return CGSizeMake(0, self.contentHeight + self.edgeInsets.bottom);
    193 }
    194 
    195 @end

    设计的思想源于tableView, 每个item的高度不该由控件本身决定,而是应该由数据决定, 通过代理告诉我每个item返回多高,边界距离, 如果没有实现代理方法,那么返回默认宽高,边界距离, 不依赖于任何数据模型

  • 相关阅读:
    第二十七节(多线程、线程的创建和启动、生命周期、调度、控制、同步)
    第二十六节(对象流,File类)
    第二十五节(转换流,打印流)
    第二十四节(Java文件流,缓冲流)
    第二十三节(String,StringBuffer,基础类型对应的 8 个包装类,日期相关类、 Random 数字 ,Enum枚举)下
    【转】perl如何避免脚本在windows中闪一下就关闭
    计算机基础(二)
    计算机基础(一)
    04 数据结构
    03 逻辑与结构
  • 原文地址:https://www.cnblogs.com/chnyang/p/5447945.html
Copyright © 2011-2022 走看看