IOS15瀑布流布局

作者: Johnson_9d92 | 来源:发表于2021-11-28 16:21 被阅读0次

    IOS15瀑布流布局

    环境

    ios 15
    xcode 13.0
    

    效果图


    瀑布流效果图

    核心源码:
    我这里使用的nib,storyBoard加载的。

    //
    //  LJWaterflowLayout.m
    //  WaterFlowDemo
    //
    //  Created by lujun on 2021/11/28.
    //
    #import "LJWaterflowLayout.h"
    static const CGFloat LJDefaultColumnCount = 3;
    static const CGFloat LJDefaultColumnMargin = 10;
    static const CGFloat LJDefaultRowMargin = 10;
    static const UIEdgeInsets LJDefaultEdgeInsets = {10,10,10,10};
    @interface LJWaterflowLayout()
    @property(nonatomic,strong)NSMutableArray *attrsArr;
    @property (nonatomic, assign) CGFloat contentHeight;
    @property(nonatomic,strong)NSMutableArray *columnHeights;
    - (CGFloat)rowMargin;
    - (CGFloat)columnMargin;
    - (NSInteger)columnCount;
    - (UIEdgeInsets)edgeInsets;
    @end
    @implementation LJWaterflowLayout
    - (CGFloat)rowMargin
    {
        if ([self.delegate respondsToSelector:@selector(rowMarginInWaterflowLayout:)]) {
            return [self.delegate rowMarginInWaterflowLayout:self];
        } else {
            return LJDefaultRowMargin;
        }
    }
    
    - (CGFloat)columnMargin
    {
        if ([self.delegate respondsToSelector:@selector(columnMarginInWaterflowLayout:)]) {
            return [self.delegate columnMarginInWaterflowLayout:self];
        } else {
            return LJDefaultColumnMargin;
        }
    }
    
    - (NSInteger)columnCount
    {
        if ([self.delegate respondsToSelector:@selector(columnCountInWaterflowLayout:)]) {
            return [self.delegate columnCountInWaterflowLayout:self];
        } else {
            return LJDefaultColumnCount;
        }
    }
    
    - (UIEdgeInsets)edgeInsets
    {
        if ([self.delegate respondsToSelector:@selector(edgeInsetsInWaterflowLayout:)]) {
            return [self.delegate edgeInsetsInWaterflowLayout:self];
        } else {
            return LJDefaultEdgeInsets;
        }
    }
    
    - (void)prepareLayout{
        [super prepareLayout];
        self.contentHeight = 0;
        //[self.collectionView setShowsVerticalScrollIndicator:NO];
        [self.columnHeights removeAllObjects];
        for(NSInteger i=0;i<LJDefaultColumnCount;i++){
            [self.columnHeights addObject:@(LJDefaultEdgeInsets.top)];
        }
        [self.attrsArr removeAllObjects];
        NSInteger count = [self.collectionView numberOfItemsInSection:0];
        for(NSInteger i = 0;i < count; i++){
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
            UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
            [self.attrsArr addObject:attrs];
         }
    }
    
    - (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
        return  self.attrsArr;
    }
    
    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
        // 创建布局属性
        UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
        // collectionView的宽度
    //    CGFloat collectionViewW = [UIScreen mainScreen].bounds.size.width;
        CGFloat collectionViewW = self.collectionView.frame.size.width;
        
        // 设置布局属性的frame
        CGFloat w = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin) / self.columnCount;
        CGFloat h = [self.delegate waterflowLayout:self heightForItemAtIndex:indexPath.item itemWidth:w];
        // 找出高度最短的那一列
        NSInteger destColumn = 0;
        CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
        for (NSInteger 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;
        }
        attrs.frame = CGRectMake(x, y, w, h);
        // 更新最短那列的高度
        self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));
        // 记录内容的高度
        CGFloat columnHeight = [self.columnHeights[destColumn] doubleValue];
        if (self.contentHeight < columnHeight) {
            self.contentHeight = columnHeight;
        }
        return attrs;
    }
    
    - (CGSize)collectionViewContentSize{
        return CGSizeMake(0, self.contentHeight + self.edgeInsets.bottom);
    }
    - (NSMutableArray *)columnHeights{
        if(!_columnHeights){
            _columnHeights = [NSMutableArray array];
        }
        return _columnHeights;
    }
    - (NSMutableArray *)attrsArr{
        if(!_attrsArr){
            _attrsArr = [NSMutableArray array];
        }
        
        return _attrsArr;
    }
    @end
    

    第二段

    #import "MJExtension.h"
    #import "LJShop.h"
    //
    //  ViewController.m
    //  WaterFlowDemo
    //
    //  Created by lujun on 2021/11/28.
    //
    #import "ViewController.h"
    #import "MJRefresh.h"
    #import "LJShopCell.h"
    #import "LJWaterflowLayout.h"
    //#import "UIImageView+WebCache.h"
    #define k_title_color [UIColor whiteColor]
    #define k_main_tab_bar_color [UIColor redColor]
    #define TEXT_BIG_S_FONT18 [UIFont systemFontOfSize:24]
    @interface ViewController () <LJWaterflowLayoutDelegate>
    @property(nonatomic,strong)NSMutableArray *shops;
    @end
    @implementation ViewController
    - (NSMutableArray *)shops{
        if(!_shops){
            _shops = [NSMutableArray array];
        }
        return _shops;
    }
    static NSString * const reuseIdentifier = @"shop";
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self setupLayout];
        [self setupRefresh];
        if (@available(iOS 15.0, *)) {
            UINavigationBarAppearance *appperance = [[UINavigationBarAppearance alloc] init];
            //添加背景色
            appperance.backgroundColor = k_main_tab_bar_color;
            appperance.shadowImage = [[UIImage alloc]init];
            appperance.shadowColor = nil;
            //设置字体颜色大小
            [appperance setTitleTextAttributes:@{NSForegroundColorAttributeName:k_title_color,NSFontAttributeName:TEXT_BIG_S_FONT18}];
            self.navigationController.navigationBar.standardAppearance = appperance;
            self.navigationController.navigationBar.scrollEdgeAppearance = appperance;
            self.navigationController.navigationBar.compactAppearance = appperance;
            self.navigationController.navigationBar.compactScrollEdgeAppearance = appperance;
        }
         self.navigationItem.title = @"瀑布流布局";
    //   [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
        [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([LJShopCell class]) bundle:nil] forCellWithReuseIdentifier:reuseIdentifier];
       LJWaterflowLayout * watet  = (LJWaterflowLayout *) [self.collectionView collectionViewLayout];
        watet.delegate = self;
    }
    - (CGFloat)waterflowLayout:(LJWaterflowLayout *)waterflowLayout heightForItemAtIndex:(NSUInteger)index itemWidth:(CGFloat)itemWidth{
    //    NSLog(@"%s",__func__);
    //    NSLog(@"大军");
        LJShop *shop = self.shops[index];
        return  itemWidth * shop.h / shop.w;
    }
    -(void)setupLayout{
        
    }
    -(void)setupRefresh{
        self.collectionView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewShops)];
        [self.collectionView.header beginRefreshing];
        self.collectionView.footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreShops)];
        self.collectionView.footer.hidden = NO;
    }
    -(void)loadMoreShops{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSArray *shops = [LJShop objectArrayWithFilename:@"mogujie.plist"];
           // [self.shops removeAllObjects];
            [self.shops addObjectsFromArray:shops];
            [self.collectionView reloadData];
            [self.collectionView.footer endRefreshing];
         });
    }
    -(void)loadNewShops{
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSArray *shops = [LJShop objectArrayWithFilename:@"mogujie.plist"];
            [self.shops removeAllObjects];
            [self.shops addObjectsFromArray:shops];
            [self.collectionView reloadData];
            [self.collectionView.header endRefreshing];
         });
    }
    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
       return 1;
    }
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
        self.collectionView.footer.hidden = self.shops.count == 0;
        return self.shops.count;
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
        LJShopCell *cell  = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
        cell.shop = self.shops[indexPath.item];
        return cell;
    }
    #pragma mark - WaterFlowLayout的代理方法,总共4个
    - (CGFloat)rowMarginInWaterflowLayout:(LJWaterflowLayout *)waterflowLayout{
        return  10;
    }
    - (CGFloat)columnCountInWaterflowLayout:(LJWaterflowLayout *)waterflowLayout{
        return 3;
    }
    @end
    

    相关文章

      网友评论

        本文标题:IOS15瀑布流布局

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