专栏首页编程语言Swift:瀑布流 网络加载图片 Swift5

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

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

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

上代码:

//
//  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链接

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python:Python实现批量刷单

    菜菜不吃蔡
  • swift 中类(class)和结构体(struct)区别

    引用类型:将一个对象赋值给另一个对象时,系统不会对此对象进行拷贝,而会将指向这个对象的指针赋值给另一个对象,当修改其中一个对象的值时,另一个对象的值会随之改变。

    菜菜不吃蔡
  • Python:Python 本地模拟HTTP,post,get

    1.Python CGI响应HTTPget/post请求,test.py(Python CGI 配置请查看上篇文章)

    菜菜不吃蔡
  • iOS runtime--获取类信息

    在iOS中可以通过runtime获取一个类的相关信息:有哪些方法、有哪些协议、有哪些属性、有哪些成员变量。安排的明明白白,老铁O(∩_∩)O哈哈~

    用户6094182
  • 为什么一个参与其中的用户社区可以开发出更好的软件[Openstack]

    想象一下,发布一个基于开源软件的大型新基础设施服务,却发现您部署的产品发展得如此之快,以至于您发布的版本的文档不再可用。在布隆伯格,我们在部署OpenStack...

    用户6667850
  • SHA256密码碰撞

    偏有宸机
  • PyTorch最佳实践,怎样才能写出一手风格优美的代码

    虽然这是一个非官方的 PyTorch 指南,但本文总结了一年多使用 PyTorch 框架的经验,尤其是用它开发深度学习相关工作的最优解决方案。请注意,我们分享的...

    机器之心
  • 我对let和const理解

    ​let和const是es6新出的两种变量声明的方式,接下来我来分别针对这两个,聊一聊。

    嘿嘿嘿
  • 【译】《Understanding ECMAScript6》- 第一章-基础知识(二)

    块绑定 JavaScript中使用var进行变量声明的机制非常怪异。在大多数C系列的编程语言中,变量的创建是在被声明的时刻同时进行的。但是JavaScript并...

    寒月十八
  • EasyNVR H5无插件直播方案前端构建之:引用videojs无法自动播放

    使用videojs来进行视频播放,videojs本身自带自动播放属性; 通过添加autoplay(),来完成视频播放的自动加载;

    EasyNVR

扫码关注云+社区

领取腾讯云代金券