• UICollectionView的简单使用(二)— 瀑布流(石工布局)


      有了上一篇的基础,发现现在常用UICollectionView的布局是瀑布流(石工布局),首先我看看默认大小不一的布局。

    1.默认布局

      我们在ViewController.m文件添加一下代码

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
        CGFloat randomHeight = 100 + (arc4random() % 140);
        return CGSizeMake(100, randomHeight);//100-240之间
    }

      模拟器运行如下:

      这就是默认的情况,但不是我们想要的情况。

    2.瀑布流(石工布局)

      接下来就要创建一个UICollectionViewLayout的子类,布局子类覆盖父类的方法

      

    2.1 在YFCollectionViewLayout.h文件中添加

    #import <UIKit/UIKit.h>
    
    @class YFCollectionViewLayout;
    
    @protocol YFCollectionViewLayoutDelegate <NSObject>
    @required
    - (CGFloat)collectionView:(UICollectionView *) collectionView
                       layout:(YFCollectionViewLayout *)layout
     heightForItemAtIndexPath:(NSIndexPath *) indexPath;
    
    @end
    
    @interface YFCollectionViewLayout : UICollectionViewLayout
    /**
     *  列数
     */
    @property (nonatomic, assign) NSUInteger numberOfColumns;
    /**
     *  间距
     */
    @property (nonatomic, assign) CGFloat interItemSpacing;
    @property (nonatomic, weak)  id<YFCollectionViewLayoutDelegate> delegate;
    
    @end

    2.2  在YFCollectionViewLayout.m文件中

    子类需要覆盖的方法有

    /**
     *  布局准备方法,可以把一些计算的东西放到这里
     */
    - (void)prepareLayout;
    /**
     *  每个子控件的一些属性
     */
    - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
    /**
     *  集合视图整体大小
     *
     */
    - (CGSize)collectionViewContentSize;
    //
    //  YFCollectionViewLayout.m
    //  WaterfallFlowCollection
    //
    //  Created by apple on 15/12/15.
    //  Copyright © 2015年 蓝天的梦想. All rights reserved.
    //
    
    #import "YFCollectionViewLayout.h"
    
    @interface YFCollectionViewLayout ()
    /**
     *  最后列的Y值
     */
    @property (nonatomic, strong) NSMutableDictionary *lastYValueForColumn;
    /**
     * 布局信息
     */
    @property (nonatomic, strong) NSMutableDictionary *layoutInfo;
    @end
    
    @implementation YFCollectionViewLayout
    
    /**
     *  布局准备方法,可以把一些计算的东西放到这里
     */
    -(void) prepareLayout {
        
         [super prepareLayout];
        
        self.lastYValueForColumn = [NSMutableDictionary dictionary];
        CGFloat currentColumn = 0;
        CGFloat fullWidth = self.collectionView.frame.size.width;
        CGFloat availableSpaceExcludingPadding = fullWidth - (self.interItemSpacing * (self.numberOfColumns + 1));
        CGFloat itemWidth = availableSpaceExcludingPadding / self.numberOfColumns;
        self.layoutInfo = [NSMutableDictionary dictionary];
        NSIndexPath *indexPath;
        NSInteger numSections = [self.collectionView numberOfSections];
        
        for(NSInteger section = 0; section < numSections; section++)  {
            
            NSInteger numItems = [self.collectionView numberOfItemsInSection:section];
            for(NSInteger item = 0; item < numItems; item++){
                indexPath = [NSIndexPath indexPathForItem:item inSection:section];
                
                UICollectionViewLayoutAttributes *itemAttributes =
                [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
                
                CGFloat x = self.interItemSpacing + (self.interItemSpacing + itemWidth) * currentColumn;
                CGFloat y = [self.lastYValueForColumn[@(currentColumn)] doubleValue];
                CGFloat height = [((id<YFCollectionViewLayoutDelegate>)self.collectionView.delegate)
                                  collectionView:self.collectionView
                                  layout:self
                                  heightForItemAtIndexPath:indexPath];
                
                itemAttributes.frame = CGRectMake(x, y, itemWidth, height);
                y+= height;
                y += self.interItemSpacing;
                
                self.lastYValueForColumn[@(currentColumn)] = @(y);
                
                currentColumn ++;
                if(currentColumn == self.numberOfColumns) currentColumn = 0;
                self.layoutInfo[indexPath] = itemAttributes;
            }
        }
    }
    
    /**
     *  每个子控件的一些属性
     */
    - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
       NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];
        
        [self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
                                                             UICollectionViewLayoutAttributes *attributes,
                                                             BOOL *stop) {
            
            if (CGRectIntersectsRect(rect, attributes.frame)) {
                [allAttributes addObject:attributes];
            }
        }];
        return allAttributes;
    }
    
    /**
     *  集合视图整体大小
     *
     */
    -(CGSize) collectionViewContentSize {
        
        NSUInteger currentColumn = 0;
        CGFloat maxHeight = 0;
        do {
            CGFloat height = [self.lastYValueForColumn[@(currentColumn)] doubleValue];
            if(height > maxHeight)
                maxHeight = height;
            currentColumn ++;
        } while (currentColumn < self.numberOfColumns);
        
        return CGSizeMake(self.collectionView.frame.size.width, maxHeight);
    }
    
    @end

    打开Storyboard的文件,给CollectionViewLayout设置类名

    打开ViewCollection.m文件,拖线并设置代理

    设置间距和列数

    设置代理方法

    模拟器运行结果如下

    下载地址:https://github.com/yifazhang/WaterfallFlowCollection

  • 相关阅读:
    全文搜索(AB-2)-权重
    全文搜索(A-2)-推荐算法
    全文检索(AB-1)-相关领域
    全文搜索(A)-相关性
    ElasticSearch全文搜索引擎(A)
    mvc 的HtmlHelper
    left join 与left outer join的区别
    ms sqlserver数据库建索引
    w3c xml
    System and method for critical address space protection in a hypervisor environment
  • 原文地址:https://www.cnblogs.com/zyfblog/p/5048841.html
Copyright © 2020-2023  润新知