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

2020-01-18 18:13:34于丽

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

<1>第一种

效果图如下所示:
ios瀑布流的实现,ios瀑布流实现原理,ios瀑布流的实现原理

这种实现方法的思路: 

1)首先调用随机函数,产生随机高度,并把它保存到数组中


 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  CGFloat cellW = 100;
  CGFloat cellH = 100 + (arc4random() % 80);
  [self.heightArrayM addObject:@(cellH)];
  
  return CGSizeMake(cellW, cellH);
  
}

2)在设置cell的frame的地方,通过取余,取整确定cell的高度,并设定cell的frame


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  
  UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
  //当前处于多少行
  NSInteger num1 = indexPath.row / count;
  //当前处于多少列
  int num2 = indexPath.row % count;
  CGFloat cellX = num2 * 100 + (num2 + 1) * margin;
  CGFloat cellY = 0;
  for (int i = 0; i < num1; i++) {
    NSInteger position = num2 + i * 3;
    cellY += [self.heightArrayM[position] floatValue] + margin;
  }
  CGFloat cellW = 100;
  CGFloat cellH = cellHeight;
  cell.frame = CGRectMake(cellX, cellY, cellW, cellH);
//  cell.backgroundColor = [UIColor redColor];
  cell.backgroundColor = [UIColor colorWithRed:(arc4random() % 250) / 250.0 green:(arc4random() % 250) / 250.0 blue:(arc4random() % 250) / 250.0 alpha:1.0];
  
//  NSLog(@"%@", NSStringFromCGRect(cell.frame)); 
  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 (weak, nonatomic) IBOutlet UICollectionView *collectionView;
@property (nonatomic, strong) NSMutableArray *heightArrayM;

@end

@implementation ViewController

- (NSMutableArray *)heightArrayM {
  if (_heightArrayM == nil) {
    _heightArrayM = [NSMutableArray array];
  }
  return _heightArrayM;
}

- (void)viewDidLoad {
  [super viewDidLoad];
  
  [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:ID];
  self.collectionView.dataSource = self;
  self.collectionView.delegate = self;
  //设置collectionView
  [self setupCollectionView];
}

//设置collectionView的布局
- (UICollectionViewFlowLayout *)setupCollectionLayout {
  UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
  
  flowLayout.minimumInteritemSpacing = margin;
  flowLayout.minimumLineSpacing = margin;
  flowLayout.sectionInset = UIEdgeInsetsMake(margin, margin, margin, margin);
  return flowLayout;
}

//设置collectionView
- (void)setupCollectionView {
  self.collectionView.collectionViewLayout =[self setupCollectionLayout];
  
}

#pragma mark - UICollectionViewDataSouce
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  return 60;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  
  UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
  //当前处于多少行
  NSInteger num1 = indexPath.row / count;
  //当前处于多少列
  int num2 = indexPath.row % count;
  CGFloat cellX = num2 * 100 + (num2 + 1) * margin;
  CGFloat cellY = 0;
  for (int i = 0; i < num1; i++) {
    NSInteger position = num2 + i * 3;
    cellY += [self.heightArrayM[position] floatValue] + margin;
  }
  CGFloat cellW = 100;
  CGFloat cellH = cellHeight;
  cell.frame = CGRectMake(cellX, cellY, cellW, cellH);
//  cell.backgroundColor = [UIColor redColor];
  cell.backgroundColor = [UIColor colorWithRed:(arc4random() % 250) / 250.0 green:(arc4random() % 250) / 250.0 blue:(arc4random() % 250) / 250.0 alpha:1.0];
  
//  NSLog(@"%@", NSStringFromCGRect(cell.frame)); 
  return cell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  CGFloat cellW = 100;
  CGFloat cellH = 100 + (arc4random() % 80);
  [self.heightArrayM addObject:@(cellH)];
  
  return CGSizeMake(cellW, cellH);
  
}
@end