zoukankan      html  css  js  c++  java
  • iOS 瀑布流之栅格布局

    代码地址如下:
    http://www.demodashi.com/demo/14760.html

    一 、效果预览

    实现的栅格布局效果示意图

    二、确定需求

    由下面的需求示意图可知模块的最小单位是正方形,边长是屏幕宽除去边距间隔后的四等份,而每个模块的样式有小正方形(1:1)、大正方形(2:2)、横长方形(2:1)、纵长方形(1:2),动态的根据服务器下发模块样式绘制布局,可以横向滑动,限定为两行的高度。
    注意:上面的示意宽高比是约等于,忽略了间距,计算的时候千万别忘了。

    需求示意图

    三、实现思路

    由上需求分析可知,我们可以让后台每个模块下发width和height两个字段,字段的值是1或2就行了,然后我们就能根据宽高字段来确定模块的宽高了。现在宽高有了,我们怎么来绘制模块呢?
    答案当然是用UICollectionView了,然后自定义流水布局UICollectionViewLayout,主要代码如下:计算记录每一个cell对应的布局属性。瀑布流的创建我已在之前的 iOS 瀑布流封装 文章中写过了,这次只是多了个栅格布局的瀑布流样式,可以下载当前最新示例Demo查看。

    /** 返回indexPath位置cell对应的布局属性*/
    - (CGRect)itemFrameOfHorizontalGridWaterFlow:(NSIndexPath *)indexPath{
        //collectionView的高度
        CGFloat collectionH = self.collectionView.frame.size.height;
        //设置布局属性item的frame
        CGFloat h = [self.delegate waterFlowLayout:self sizeForItemAtIndexPath:indexPath].height;
        CGFloat w = [self.delegate waterFlowLayout:self sizeForItemAtIndexPath:indexPath].width;
        
        CGFloat x = 0;
        CGFloat y = 0;
      
        //找出宽度最短的那一行
        NSInteger destRow = 0;
        CGFloat minRowWidth = [self.rowWidths[destRow] doubleValue];
        for (NSInteger i = 1; i < self.rowWidths.count; i++) {
            //取出第i行
            CGFloat rowWidth = [self.rowWidths[i] doubleValue];
            if (minRowWidth > rowWidth) {
                minRowWidth = rowWidth;
                destRow = i;
            }
        }
        
        y = destRow == 0 ? self.edgeInsets.top : self.edgeInsets.top + h + self.rowMargin;
        
        x = [self.rowWidths[destRow] doubleValue] == self.edgeInsets.left ? self.edgeInsets.left : [self.rowWidths[destRow] doubleValue] + self.columnMargin;
        //更新最短那行的宽度
        if (h >= collectionH - self.edgeInsets.bottom - self.edgeInsets.top) {
            x = [self.rowWidths[destRow] doubleValue] == self.edgeInsets.left ? self.edgeInsets.left : self.maxRowWidth + self.columnMargin;
            for (NSInteger i = 0; i < 2; i++) {
                self.rowWidths[i] = @(x + w);
            }
        }else{
            self.rowWidths[destRow] = @(x + w);
        }
        //记录最大宽度
        if (self.maxRowWidth < x + w) {
            self.maxRowWidth = x + w ;
        }
        return CGRectMake(x, y, w, h);
    }
    

    后台下发字段格式示意图

    功能描述:WSLWaterFlowLayout 是在继承于UICollectionViewLayout的基础上封装的带头脚视图的瀑布流控件。目前支持竖向瀑布流(item等宽不等高、支持头脚视图)、水平瀑布流(item等高不等宽 不支持头脚视图)、竖向瀑布流( item等高不等宽、支持头脚视图)、栅格布局瀑布流 4种样式的瀑布流布局。

    WSLWaterFlowLayout

    四、项目结构

    iOS 瀑布流之栅格布局

    代码地址如下:
    http://www.demodashi.com/demo/14760.html

  • 相关阅读:
    jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
    jQuery 源码解析(二十三) DOM操作模块 替换元素 详解
    jQuery 源码解析(二十二) DOM操作模块 复制元素 详解
    jQuery 源码分析(二十一) DOM操作模块 删除元素 详解
    jQuery 源码分析(二十) DOM操作模块 插入元素 详解
    jQuery 源码分析(十九) DOM遍历模块详解
    python 简单工厂模式
    python 爬虫-协程 采集博客园
    vue 自定义image组件
    微信小程序 image组件坑
  • 原文地址:https://www.cnblogs.com/demodashi/p/10480204.html
Copyright © 2011-2022 走看看