iOS 开发每天分享优质文章iOS学习笔记iOS高阶UI相关

iOS之瀑布流demo练习

2016-10-15  本文已影响299人  阿拉斯加的狗

DEMO示例展示

demo展示.gif

1<在实现其中的几个必要的方法

/** 
 *   准备布局
 */
- (void)prepareLayout{
}

/**
 *   决定cell的排布
 */
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
}

/**
 *   布局item的具体位置
 */
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
}

/**
 *   布局的滚动范围
 */
- (CGSize)collectionViewContentSize{
}
/** 存到所有cell的布局 */
@property (nonatomic,strong)NSMutableArray *attsArray;
/** 存放所有列的当前高度 */
@property (nonatomic,strong)NSMutableArray *columnHeights;

/**
 *   布局item的具体位置
 */
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewLayoutAttributes *atts = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    //布局item
    CGFloat collectionViewW = self.collectionView.frame.size.width;
    
    CGFloat W = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin) / self.columnCount;
    
    //获取到collectionView的item的最短的那一列
    NSUInteger destColumn = 0;
    CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
    for (NSUInteger i = 1; i < self.columnCount; i ++) {
        
        //获取i行的高度
        CGFloat columnHeight = [self.columnHeights[i] doubleValue];
        if (minColumnHeight > columnHeight) {
            minColumnHeight = columnHeight;
            destColumn = i;
        }
        
    }
    
    CGFloat X = self.edgeInsets.left + destColumn * (W + self.columnMargin);
    
    CGFloat Y = minColumnHeight;
    if (Y != self.edgeInsets.top) {
        Y += self.rowMargin;
    }
    CGFloat H = [self.delegate waterViewLayout:self heightForItemAtIndex:indexPath.item itemWidth:W];
    
    atts.frame = CGRectMake(X, Y, W, H);
    
    //更新最短的高度
    self.columnHeights[destColumn] = @(CGRectGetMaxY(atts.frame));
    
    return atts;
}


/**
 *   布局的滚动范围
 */
- (CGSize)collectionViewContentSize {

    CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];
    for (NSUInteger i = 1; i < self.columnCount; i ++) {
        
        //获取i行的高度
        CGFloat columnHeight = [self.columnHeights[i] doubleValue];
        if (columnHeight > maxColumnHeight) {
            maxColumnHeight = columnHeight;
            
        }
        
    }
    
    return CGSizeMake(0, maxColumnHeight + self.edgeInsets.bottom);
}

以上的就是核心的瀑布流的算法.

最后想分享的是这个瀑布流笔者封装了起来留有所在行数的间距跟所在列的接口,不需要以后每次都会重新写自定义流水布局.只许进行测试调用所在列为多少即可.

#import <UIKit/UIKit.h>
@class WKWaterViewLayout;
@protocol WKWaterViewLayoutDelegate <NSObject>

@required
/** 外部所在的尺寸计算布局内的高度 */
- (CGFloat)waterViewLayout:(WKWaterViewLayout *)waterLayout heightForItemAtIndex:(NSUInteger)index itemWidth:(CGFloat)itemWidth;

@optional
/** 瀑布流所在的列数 */
- (CGFloat)columnCountInWaterflowLayout:(WKWaterViewLayout *)waterflowLayout;
/** item的每一列的边距 */
- (CGFloat)columnMarginInWaterflowLayout:(WKWaterViewLayout *)waterflowLayout;
/** item的每一行的边距 */
- (CGFloat)rowMarginInWaterflowLayout:(WKWaterViewLayout *)waterflowLayout;
/** 内边距 */
- (UIEdgeInsets)edgeInsetsInWaterflowLayout:(WKWaterViewLayout *)waterflowLayout;

@end

@interface WKWaterViewLayout : UICollectionViewLayout

@property (nonatomic,weak)id<WKWaterViewLayoutDelegate> delegate;

@end

demo 下载地址:https://github.com/aryehToDog/WK-WaterFlowLaout/tree/master

上一篇 下一篇

猜你喜欢

热点阅读