• iOS UICollectionView 瀑布流


    在学习开源项目:豆瓣相册-精选集https://github.com/cbknight/CBDoubanAlbum,使用到瀑布流展示图片,因此学习下iOS瀑布流。

    1. UIScrollView 与 UICollectionView

    UISCrollView:

    优点:

    1.灵活调节子控件,可边展示,边编辑图片(casatwy架构的App:Play+)。

    缺点:

    1.需要自己缓存子控件(未显示在scrollview上);

    2.需要监听scrollview滚动,不显的控件从父控件上移除,添加到缓存set集合中,以便于复用;

    3.需要布局每个子控件。

    UIScollectionView:

    优点:

    1.UIScollectionView系统已做好了缓存机制,可以复用,简单易用。

    缺点:

    2.仅显示。

    2. UICollectionView实现:UICollectionViewDataSource和UICollectionViewDelegateFlowLayout

    1. 自定义流水布局中,指定滚动方向、默认列数、行间距、列间距、以及指定cell的大小itemSize:

    1 #pragma mark - UICollectionViewDataSource
    2 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
    3 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
    4 
    5 #pragma mark - UICollectionViewDelegateFlowLayout
    6 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
    7 - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;

    3. 继承UICollectionViewCell:

    1. 简单Demo,就展示ImageView:

    1 @property (nonatomic, strong) UIImageView *imageView;

    2. 使用AutoLayout布局imageView:

     1 - (instancetype)initWithFrame:(CGRect)frame
     2 {
     3     self = [super initWithFrame:frame];
     4     if (self) {
     5         self.imageView = [[UIImageView alloc] init];
     6         self.imageView.translatesAutoresizingMaskIntoConstraints = NO;
     7         [self addSubview:self.imageView];
     8         
     9         NSArray *fillWidth = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_imageView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageView)];
    10         NSArray *fillHeight = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_imageView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageView)];
    11         [self addConstraints:fillWidth];
    12         [self addConstraints:fillHeight];
    13     }
    14     return self;
    15 }

    4. 继承UICollectionViewFlowLayout

    1. columnMaxYs数组(记录当前每一列的最大Y值),假如3列,我们就提供一个3个元素的数组,记录所有布局属性:

    1 @property (nonatomic, assign) NSInteger column; // 列数
    2 
    3 @property (nonatomic, assign) id<UICollectionViewDelegateFlowLayout> delegate;
    4 @property (nonatomic, strong) NSMutableArray *columnMaxYs; // 每一列的最大Y值
    5 @property (nonatomic, strong) NSMutableDictionary *attributeDict; // 存放cell的布局属性
    6 @property (nonatomic, assign) NSUInteger cellCount; // cell的个数

    2. 在prepareLayout方法中 初始化:

    至于为什么在prepareLayout方法中初始化,而不是在init方法初始化:

    是因为,该方法每次刷新都会调用,而init方法中只会在创建布局对象的时候只执行一次,

    例如:如果进行下拉刷新最新数据的时候,需求重新初始化数据,而如果我们使用的是init方法的话,并不会调用也就并不会清除之前的然后初始化, 而使用该方法prepareLayout可以办到,因为它会再次调用,而init不会调用。

    1 - (void)prepareLayout;

    3. 在layoutAttributesForItemAtIndexPath: 来调整 Cell的布局属性 ,指定Cell的 frame 。

    1 - (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;

    1.在该方法中拿到当前cell的默认布局属性attrs,进行下面的调整,就可以实现瀑布流了

    2.遍历columnMaxYs数组,需要找出最短一列的 列号 与 最大Y值

    3.确定当前Cell的 存放的x.y位置 以及widht与height

       —> width:根据屏幕宽度与列数以及每列的宽度求出. height:服务器返回的

       —> x:需要根据当前最短一列的列号与Cell的宽度与间距可以求出来;y : 可以根据当前最短一列的最大Y值 + 行间距可以求出

    4.重新设置修改当前Cell的布局属性attrs 的 frame即可。

      —> 之前已经拿到当前Cell的 默认布局属性,以及上一步已经获取到当前Cell需要存放的x.y位置后,

    5.将修改Cell布局属性之后的,当前列当前Cell的Y值最大,所有我们要将该值记录到数组columnMaxYs中,以便下次对比

    4. 在layoutAttributesForElementsInRect:方法(返回布局信息,如果忽略传入的rect一次性将所有的cell布局信息返回,图片过多时性能会很差

    1 - (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;

    5. 设置collectionView的contentSize,它才会滚动:

    1 - (CGSize)collectionViewContentSize;

    5.写的一个简单的瀑布流 Demo Github

    6.一个开源瀑布流,可以使用Cocoapods:DDCollectionViewFlowLayout

  • 相关阅读:
    explicit构造函数
    Windows内核编程之:结构化异常处理
    驱动对象DRIVER_OBJECT
    Windows内核编程之:内存管理
    Windows内核编程之:链表
    Windows内核编程之:返回状态值
    设备对象DEVICE_OBJECT
    数据恢复
    Windows内核编程之:数据类型
    Windows内核编程之:检查内存的可用性
  • 原文地址:https://www.cnblogs.com/chrisbin/p/5473804.html
Copyright © 2020-2023  润新知