前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Swift:瀑布流 网络加载图片 Swift5

Swift:瀑布流 网络加载图片 Swift5

作者头像
菜菜不吃蔡
发布2019-10-30 11:49:41
1.6K0
发布2019-10-30 11:49:41
举报
文章被收录于专栏:编程语言

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/Mayxc/article/details/102800577

上代码:

代码语言:javascript
复制
//
//  WaterfallLayout.swift
//  WaterfallSwift
//
//  Created by admin on 2019/10/11.
//  Copyright © 2019 admin. All rights reserved.
//

import UIKit

/// 瀑布流代理
@objc protocol WaterfallLayoutDataSource : class {
    
    /// 指定ITEM的高度
    ///
    /// - Parameters:
    ///   - layout: 布局
    ///   - indexPath: 位置
    /// - Returns: 高度比例
    func waterfallLayout(_ layout : WaterfallLayout, indexPath : IndexPath) -> CGFloat
    
    /// 瀑布流一共有多少列,默认时三列
    /// - Parameter layout: 布局
    /// - Returns: 列数
    @objc optional func numberOfColsInWaterfallLayout(_ layout : WaterfallLayout) -> Int
}

class WaterfallLayout: UICollectionViewFlowLayout {
    
    // MARK: 对外提供属性
    // 瀑布流数据源代理
    weak var dataSource : WaterfallLayoutDataSource?
    
    // MARK: 私有属性
    // 布局属性数组
    private lazy var attrsArray : [UICollectionViewLayoutAttributes] = [UICollectionViewLayoutAttributes]()
    
    // 最高的高度
    private var maxH : CGFloat = 0
    
    //索引
    private var startIndex = 0
}

extension WaterfallLayout {
    
    override func prepare() {
        super.prepare()
        
        //获取item的个数
        let itemCount = collectionView!.numberOfItems(inSection: 0)
        
        //获取列数
        let cols = dataSource?.numberOfColsInWaterfallLayout?(self) ?? 2
        //每一列的高度累计
         var colHeights = Array(repeating: self.sectionInset.top, count: cols)
        
        //计算Item的宽度(屏幕宽度铺满)
        let itemW = (collectionView!.bounds.width - self.sectionInset.left - self.sectionInset.right - self.minimumInteritemSpacing * CGFloat(cols - 1)) / CGFloat(cols)
        attrsArray = Array.init()
        //计算所有的item的属性
        for i in 0..<itemCount {
            // 设置每一个Item位置相关的属性
            let indexPath = IndexPath(item: i, section: 0)
            
            // 根据位置创建Attributes属性
            let attrs = UICollectionViewLayoutAttributes(forCellWith: indexPath)
            
            // 获取CELL的高度
            guard var height = dataSource?.waterfallLayout(self, indexPath: indexPath) else {
                fatalError("请设置数据源,并且实现对应的数据源方法")
            }
            height = height * itemW
            //取出当前列所属的列索引
            let index = i % cols
            
            //获取当前列的总高度
            var colH = colHeights[index]
            
            //将当前列的高度在加载当前ITEM的高度
            colH = colH + height + minimumLineSpacing
            
            //重新设置当前列的高度
            colHeights[i % cols] = colH
            
            // 5.设置item的属性
            attrs.frame = CGRect(x: self.sectionInset.left + (self.minimumInteritemSpacing + itemW) * CGFloat(index), y: colH - height - self.minimumLineSpacing, width: itemW, height: height)
            
            attrsArray.append(attrs)
        }
        
        // 4.记录最大值
        maxH = colHeights.max()!
        
        // 5.给startIndex重新复制
        startIndex = itemCount
    }
}

extension WaterfallLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return attrsArray
    }
    
    override var collectionViewContentSize: CGSize {
        return CGSize(width: 0, height: maxH + sectionInset.bottom - minimumLineSpacing)
    }
}

GitHub:demo链接

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/10/29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档