微信关注
在线联系

iOS瀑布流的简单实现(Swift)

这段时间突然想到一个很久之前用到的知识-瀑布流,本来想用一个简单的方法,发现自己走入了歧途,最终只能狠下心来重写ui尊龙现金d88collectionviewflowlayout.下面我将用两种方法实现瀑布流,以及会介绍第一种实现的bug.

1 第一种



这种实现方法的思路: 


 - collectionview:collectionview layout:collectionviewlayout sizeforitematindexpath:indexpath {
 cgfloat cellw = 100;
 cgfloat cellh = 100 +  % 80);
 [self.heightarraym addobject:@];
 return cgsizemake;
}

- collectionview:collectionview cellforitematindexpath:indexpath {
 uicollectionviewcell *cell = [self.collectionview dequeuereusablecellwithreuseidentifier:id forindexpath:indexpath];
 //当前处于多少行
 nsinteger num1 = indexpath.row / count;
 //当前处于多少列
 int num2 = indexpath.row % count;
 cgfloat cellx = num2 * 100 +  * margin;
 cgfloat celly = 0;
 for  {
 nsinteger position = num2 + i * 3;
 celly += [self.heightarraym[position] floatvalue] + margin;
 cgfloat cellw = 100;
 cgfloat cellh = cellheight;
 cell.frame = cgrectmake;
// cell.backgroundcolor = [uicolor redcolor];
 cell.backgroundcolor = [uicolor colorwithred: % 250) / 250.0 green: % 250) / 250.0 blue: % 250) / 250.0 alpha:1.0];
// nslog); 
 return cell;

弊端 : 其实这种方法的弊端,相信从上面的动态图中可以看出来,当往上面滑的时候,由于cell的循环机制,下面的cell的会消失,但是由于高度不一致,同时撤销的是最后一行的cell,所以下面的cell在屏幕上就会消失.


#import "viewcontroller.h"
#define margin 10
#define count 3
#define cellheight [self.heightarraym[indexpath.row] floatvalue]
static nsstring * const id = @"cell";
@interface viewcontroller  uicollectionviewdelegate, uicollectionviewdatasource, uicollectionviewdelegateflowlayout 
@property  iboutlet uicollectionview *collectionview;
@property  nsmutablearray *heightarraym;
@implementation viewcontroller
- heightarraym {
 if  {
 _heightarraym = [nsmutablearray array];
 return _heightarraym;
- viewdidload {
 [super viewdidload];
 [self.collectionview registerclass:[uicollectionviewcell class] forcellwithreuseidentifier:id];
 self.collectionview.datasource = self;
 self.collectionview.delegate = self;
 //设置collectionview
 [self setupcollectionview];
//设置collectionview的布局
- setupcollectionlayout {
 uicollectionviewflowlayout *flowlayout = [[uicollectionviewflowlayout alloc] init];
 flowlayout.minimuminteritemspacing = margin;
 flowlayout.minimumlinespacing = margin;
 flowlayout.sectioninset = uiedgeinsetsmake;
 return flowlayout;
//设置collectionview
- setupcollectionview {
 self.collectionview.collectionviewlayout =[self setupcollectionlayout];
#pragma mark - uicollectionviewdatasouce
- collectionview:collectionview numberofitemsinsection:section {
 return 60;
- collectionview:collectionview cellforitematindexpath:indexpath {
 uicollectionviewcell *cell = [self.collectionview dequeuereusablecellwithreuseidentifier:id forindexpath:indexpath];
 //当前处于多少行
 nsinteger num1 = indexpath.row / count;
 //当前处于多少列
 int num2 = indexpath.row % count;
 cgfloat cellx = num2 * 100 +  * margin;
 cgfloat celly = 0;
 for  {
 nsinteger position = num2 + i * 3;
 celly += [self.heightarraym[position] floatvalue] + margin;
 cgfloat cellw = 100;
 cgfloat cellh = cellheight;
 cell.frame = cgrectmake;
// cell.backgroundcolor = [uicolor redcolor];
 cell.backgroundcolor = [uicolor colorwithred: % 250) / 250.0 green: % 250) / 250.0 blue: % 250) / 250.0 alpha:1.0];
// nslog); 
 return cell;
- collectionview:collectionview layout:collectionviewlayout sizeforitematindexpath:indexpath {
 cgfloat cellw = 100;
 cgfloat cellh = 100 +  % 80);
 [self.heightarraym addobject:@];
 return cgsizemake;

2 下面介绍第二种



这种实现方法就是比较成熟的了,我把它封装成一个类.其实主要是实现三个函数


 extension waterfalllayout {
 // prepare准备所有cell的布局样式
 override func prepare {
 super.prepare
 // 0.获取item的个数
 let itemcount = collectionview!.numberofitems
 // 1.获取列数
 let cols = datasource .numberofcolsinwaterfalllayout  2
 // 2.计算item的宽度
 let itemw = )) / cgfloat
 // 3.计算所有的item的属性
 for i in startindex.. itemcount {
 // 1.设置每一个item位置相关的属性
 let indexpath = indexpath
 // 2.根据位置创建attributes属性
 let attrs = uicollectionviewlayoutattributes
 // 3.随机一个高度
 guard let height = datasource .waterfalllayout else {
 fatalerror
 // 4.取出最小列的位置
 var minh = colheights.min!
 let index = colheights.index!
 minh = minh + height + minimumlinespacing
 colheights[index] = minh
 // 5.设置item的属性
 attrs.frame = cgrect * cgfloat, y: minh - height - self.minimumlinespacing, width: itemw, height: height)
 attrsarray.append
 // 4.记录最大值
 maxh = colheights.max!
 // 5.给startindex重新复制
 startindex = itemcount

2)返回设置cell样式的数组

 override func layoutattributesforelements - [uicollectionviewlayoutattributes] {
 return attrsarray
 }

3)返回当前的contentsize

override var collectionviewcontentsize: cgsize {
 return cgsize
 }

总结:

在下面我封装的这个类中,只需要遵守我的数据代理源协议并且实现我的协议中的两个方法,传给我对应得高度,可选的方法,若是不实现,会有一个默认值,就可以实现该功能.协议如下:

@objc protocol waterfalllayoutdatasource : class {
 func waterfalllayout - cgfloat
 @objc optional func numberofcolsinwaterfalllayout - int
}


import uikit
extension uicolor {
 class func randomcolor - uicolor {
 return uicolor) / 255.0, green: float) / 255.0, blue: float) / 255.0, alpha: 1.0)
private let kwatercellid = "kwatercellid"
class viewcontroller: uiviewcontroller {
 var count : int = 20
 override func viewdidload {
 super.viewdidload
 // 1.设置布局
 let layout = waterfalllayout
 layout.minimumlinespacing = 10
 layout.minimuminteritemspacing = 10
 layout.sectioninset = uiedgeinsets
 layout.datasource = self
 // 2.创建uicollectionview
 let collectionview = uicollectionview
 collectionview.datasource = self
 collectionview.register
 view.addsubview
extension viewcontroller : uicollectionviewdatasource {
 func collectionview - int {
 return count
 func collectionview - uicollectionviewcell {
 let cell = collectionview.dequeuereusablecell
 cell.backgroundcolor = uicolor.randomcolor
 if indexpath.item == count - 1 {
 count += 20
 collectionview.reloaddata
 return cell

HOME |  ABOUT US |  PORTFOLIO |  NEWS |  CONTACT US

Copyright © 2018 尊龙人生就是搏d88尊龙人生就是搏d88-尊龙现金d88 All Rights Reserved Power by DedeCms


CONTACT US
+86 02888888888