实现瀑布流,只需要重写 UICollectionViewLayout 类的3个方法:
-
prepare 准备"当collectionView即将要显示的时候以及reloadData 之后都会来调用此方法做布局前的准备"准备itemSize 最小行间距..."
- (void)prepareLayout {}
-
如果是自己来计算cell的frame之后一定要重写此方法返回collectionView的真实滚动范围
- (CGSize)collectionViewContentSize { // 取出最高那一列的列号
NSInteger maxCol =[self maxHeightCol];
return CGSizeMake(0, [self.eachColumnMaxHight[maxCol] floatValue] - self.minimumLineSpacing + self.footerReferenceSize.height);
}
- 通过输出此方法 数组中装的是一个一个的布局属性,一个布局属性对应一个cell
1.布局属性中有cell的frame
2.布局属性中还有cell的索引
3.此方法是用来计算所有cell的frame及索引,而且每一个cell只计算一次,计算完成之后就不会再重复计算
4.通过修改每一个cell对应的布局属性可以直接修改cell的frame,所以推理我们可以自己来计算每一个cell的frame最后把每一个cell对应的布局属性添加到数组中最终用此方法返回我们自己算好的frame应该可以实现瀑布流效果
// 在数组的最后还要计算footerView的frame 它的索引为0-0
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *array = [super layoutAttributesForElementsInRect:rect];
for (UICollectionViewLayoutAttributes *attr in array) {
attr.frame = CGRectMake(0, 0, 120, 130);
}
return array;
}
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
return self.attrM;
}
瀑布流的规则:图片定宽而不定高;必须拿到图片的真实宽、高,以保证图片按正常比例显示,保证美观性。
每一行图片显示完之后,下一行图片显示的顺序是:从高度最矮的那一列开始显示;所以最好定义一个可变的数组来动态的保存每一列的高。
上拉刷新加载图片:
调用UIScrollerView的代理方法:屏幕正在滚动中都会调用此方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// 如果footerView还没有出来以及正在加载中都不要再去重复加载更多
if (self.footerView == nil || self.footerView.activity.isAnimating == YES) return;
// 当footerView完全显示之后再加加载更多"而不是footerView一出来就去加载更多
if (self.collectionView.contentOffset.y + self.collectionView.bounds.size.height > CGRectGetMaxY(self.footerView.frame) ) {
// 正在加载时先让花花转起来
[self.footerView.activity startAnimating];
// 延迟去模拟网络加载
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 1.给模型数组中添加更多数据
[self loadMoreData];
// 2.让数据源方法重新执行
[self.collectionView reloadData];
// 3.让花花停止转
[self.footerView.activity stopAnimating];
// 4.把footerView属性设置为nil
self.footerView = nil;
});
}
}
网友评论