CollectionView实现瀑布流(swift)
来源:互联网 发布:c语言 面向过程 编辑:程序博客网 时间:2024/05/22 04:26
我们用纯代码实现一下瀑布流:
AppDelegate:
var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { window = UIWindow(frame: (UIScreen.mainScreen().bounds)) window?.rootViewController = WaterFlowViewController() window?.makeKeyAndVisible() return true }
- 搞一个随机色:
extension UIColor { //随机颜色 class func randomColor() ->UIColor { return UIColor(red: randomValue(), green: randomValue(), blue: randomValue(), alpha: 1) } class func randomValue()->CGFloat { return CGFloat(arc4random_uniform(256))/255 }}
- 自定义布局:
protocol WaterFlowViewLayoutDelegate:NSObjectProtocol{ //collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) ///width是瀑布流每列的宽度 func waterFlowViewLayout(waterFlowViewLayout:WaterFlowViewLayout,heightForWidth:CGFloat,atIndextPath:NSIndexPath)->CGFloat}class WaterFlowViewLayout: UICollectionViewLayout { weak var delegate:WaterFlowViewLayoutDelegate? ///所有cell的布局属性 var layoutAttributes = [UICollectionViewLayoutAttributes]() ///使用一个字典记录每列的最大Y值 var maxYDict = [Int:CGFloat]() static var Margin:CGFloat = 8 ///瀑布流四周的间距 var sectionInsert = UIEdgeInsets(top: Margin, left: Margin, bottom: Margin, right: Margin) //列间距 var columnMargin:CGFloat = Margin //行间距 var rowMargin:CGFloat = Margin ///瀑布流列数 var column = 4 var maxY:CGFloat = 0 var columnWidth:CGFloat = 0 ///prepareLayout会在调用collectionView.reloadData() override func prepareLayout() { //设置布局 //需要清空字典里面的值 for key in 0..<column { maxYDict[key] = 0 } //清空之前的布局属性 layoutAttributes.removeAll() //清空最大列的Y值 maxY = 0 ///清空列宽 columnWidth = 0 //计算每列的宽度,需要在布局之前算好 columnWidth = (UIScreen.mainScreen().bounds.width - sectionInsert.left - sectionInsert.right - (CGFloat(column) - 1)*columnMargin)/CGFloat(column) let number = collectionView?.numberOfItemsInSection(0) ?? 0 for i in 0..<number { //布局每一个cell的frame let layoutAttr = layoutAttributesForItemAtIndexPath(NSIndexPath(forItem: i, inSection: 0))! layoutAttributes.append(layoutAttr) } calcMaxY() } func calcMaxY(){ //获取最大这一列的Y //默认第0列最长 var maxYCoulumn = 0 //for 循环比较,获取最长的这列 for (key,value) in maxYDict { if value > maxYDict[maxYCoulumn]{ //key这列的Y值是最大的 maxYCoulumn = key } } //获取到Y值最大的这一列 maxY = maxYDict[maxYCoulumn]! + sectionInsert.bottom } //返回collectionViewContentSize 大小 override func collectionViewContentSize() -> CGSize { return CGSize(width: UIScreen.mainScreen().bounds.width, height: maxY) } // 返回每一个cell的布局属性(layoutAttributes) // UICollectionViewLayoutAttributes: 1.cell的frame 2.indexPath override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? { assert(delegate != nil,"瀑布流必须实现代理来返回cell的高度") let height = delegate!.waterFlowViewLayout(self, heightForWidth: columnWidth, atIndextPath: indexPath) // 找到最短的那一列,去maxYDict字典中找 // 最短的这一列 var minYColumn = 0 //通过for循环去和其他列比较 for(key, value) in maxYDict { if value < maxYDict[minYColumn] { minYColumn = key } } // minYColumn 就是短的那一列 let x = sectionInsert.left + CGFloat(minYColumn) * (columnWidth + columnMargin) //最短这列的Y值 + 行间距 let y = maxYDict[minYColumn]! + rowMargin //设置cell的frame let frame = CGRect(x: x, y: y, width: columnWidth, height: height) //更新最短这列的最大Y值 maxYDict[minYColumn] = CGRectGetMaxY(frame) //创建每个cell对应的布局属性 let layoutAttr = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath) layoutAttr.frame = frame return layoutAttr } //预加载下一页数据 override func layoutAttributesForElementsInRect(rect:CGRect) -> [UICollectionViewLayoutAttributes]{ return layoutAttributes } }
- 一个类继承UICollectionViewController,遵循:WaterFlowViewLayoutDelegate协议
class WaterFlowViewController: UICollectionViewController,WaterFlowViewLayoutDelegate { let ReuseIdentifier = "ReuseIdentifier" let layout = WaterFlowViewLayout() init(){ super.init(collectionViewLayout: layout) } override func viewDidLoad() { super.viewDidLoad() collectionView?.backgroundColor = UIColor.whiteColor() collectionView?.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: ReuseIdentifier) layout.delegate = self } func waterFlowViewLayout(waterFlowViewLayout: WaterFlowViewLayout, heightForWidth: CGFloat, atIndextPath: NSIndexPath) -> CGFloat { return CGFloat(100 + arc4random_uniform(50)) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 500 } override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier(ReuseIdentifier, forIndexPath: indexPath) cell.backgroundColor = UIColor.randomColor() return cell }}
其实就是一个自定义布局 算术的问题,看一下效果:
0 0
- CollectionView实现瀑布流(swift)
- CollectionView实现瀑布流
- collectionView实现瀑布流
- 瀑布流 collectionView实现
- collectionView实现瀑布流
- iOS collectionView实现瀑布流
- iOS使用CollectionView实现瀑布流
- 整理 collectionView 瀑布流 布局
- iOS-CollectionView 瀑布流视图
- swift瀑布流自定义布局实现
- swift简单瀑布流的实现
- CollectionView和layout的使用,瀑布流
- iOS-CollectionView瀑布流框架搭建
- CollectionView可任意调整带刷新的瀑布流
- CollectionView瀑布流添加头视图,自定义Cell计算高度
- 瀑布流(UIScrollView实现)
- Swift 使用CollectionView 实现图片轮播封装
- swift 自定义collectionView
- 深度学习文献阅读笔记(6)
- 做网站:myeclipse+tomcat+mysql环境搭建
- C语言实现封装、继承和多态
- Sumsets(递推)
- 使用Eclipse一点心得
- CollectionView实现瀑布流(swift)
- GNU assembler not found, install/update gas-preprocessor
- 20160114html学习笔记表单框架颜色脚本字符实体
- leetcode刷题,总结, 记录,备忘326
- 内存泄漏
- jenkins资料
- 解析如何读取文件形成InputSplit
- Erlang语言学习系列(四)
- ABAP屏幕基础