先上效果图
先添加一个WaterFallLayout类,做为瀑布流布局类
代码如下:
//
// WaterFallLayout.swift
//
// Created by antu on 2018/11/8.
// Copyright © 2018 antu. All rights reserved.
//
import UIKit
class WaterFallLayout: UICollectionViewFlowLayout {
// 封装一个属性,用来设置item的个数
let itemCount:Int
// 添加一个数组属性,用来存放每个item的布局信息
var attributeArray:Array<UICollectionViewLayoutAttributes>?
// 实现必要的构造方法
required init?(coder aDecoder: NSCoder) {
itemCount = 0
super.init(coder:aDecoder)
}
// 自定义一个初始化构造方法
init(itemCount:Int) {
self.itemCount = itemCount
super.init()
}
override func prepare() {
//调用父类的准备方法
super.prepare()
//设置为竖直布局
self.scrollDirection = .vertical
//初始化数组
attributeArray = Array<UICollectionViewLayoutAttributes>()
//先计算每个item的宽度,默认为两列布局
let WIDTH = (UIScreen.main.bounds.size.width-self.minimumInteritemSpacing)/2
//定义一个元组表示每一列的动态高度
var queueHieght:(one:Int,two:Int) = (0,0)
//进行循环设置
for index in 0..<self.itemCount {
//设置IndexPath,默认为一个分区
let indexPath = IndexPath(item: index, section: 0)
//创建布局属性类
let attris = UICollectionViewLayoutAttributes(forCellWith: indexPath)
//随机一个高度在80到190之间的值
let height:Int = Int(arc4random()%110+80)
//哪列高度小就把它放那列下面
//标记那一列
var queue = 0
if queueHieght.one <= queueHieght.two {
queueHieght.one += (height+Int(self.minimumInteritemSpacing))
queue = 0
} else{
queueHieght.two += (height+Int(self.minimumInteritemSpacing))
queue = 1
}
//设置item的位置
let tmpH = queue == 0 ? queueHieght.one-height : queueHieght.two-height
attris.frame = CGRect(x: (self.minimumInteritemSpacing+WIDTH)*CGFloat(queue), y: CGFloat(tmpH), width: WIDTH, height: CGFloat(height))
//添加到数组中
attributeArray?.append(attris)
}
//以最大一列的高度计算每个item高度的中间值,这样可以保证滑动范围的正确
if queueHieght.one <= queueHieght.two {
self.itemSize = CGSize(width: WIDTH, height: CGFloat(queueHieght.two*2/self.itemCount)-self.minimumLineSpacing)
} else {
self.itemSize = CGSize(width: WIDTH, height: CGFloat(queueHieght.one*2/self.itemCount)-self.minimumLineSpacing)
}
}
//将设置好存放每个item的布局信息返回
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
return attributeArray
}
}
然后就是它的使用
代码如下:
//
// FirstViewController.swift
//
//
// Created by antu on 2018/11/8.
// Copyright © 2018 antu. All rights reserved.
//
import UIKit
class FirstViewController: UIViewController , UICollectionViewDataSource , UICollectionViewDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 30
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "itemID", for: indexPath)
cell.backgroundColor = UIColor(red: CGFloat(arc4random()%255)/255, green: CGFloat(arc4random()%255)/255, blue: CGFloat(arc4random()%255)/255, alpha: 1)
return cell
}
// 点击事件
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("点击了第\(indexPath.row)个item")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//创建瀑布流视图布局类
let layout = WaterFallLayout(itemCount: 30)
//创建集合视图
let collectionView = UICollectionView(frame: self.view.frame,collectionViewLayout: layout)
collectionView.dataSource = self
collectionView.delegate = self
//注册载体数据类
collectionView.register(NSClassFromString("UICollectionViewCell"), forCellWithReuseIdentifier: "itemID")
self.view.addSubview(collectionView)
}
}