實(shí)現(xiàn)瀑布流,只需要重寫(xiě) UICollectionViewLayout 類(lèi)的3個(gè)方法:
prepare 準(zhǔn)備"當(dāng)collectionView即將要顯示的時(shí)候以及reloadData 之后都會(huì)來(lái)調(diào)用此方法做布局前的準(zhǔn)備"準(zhǔn)備itemSize 最小行間距..."
- (void)prepareLayout {}如果是自己來(lái)計(jì)算cell的frame之后一定要重寫(xiě)此方法返回collectionView的真實(shí)滾動(dòng)范圍
- (CGSize)collectionViewContentSize { // 取出最高那一列的列號(hào)
NSInteger maxCol =[self maxHeightCol];
return CGSizeMake(0, [self.eachColumnMaxHight[maxCol] floatValue] - self.minimumLineSpacing + self.footerReferenceSize.height);
}
- 通過(guò)輸出此方法 數(shù)組中裝的是一個(gè)一個(gè)的布局屬性,一個(gè)布局屬性對(duì)應(yīng)一個(gè)cell
1.布局屬性中有cell的frame
2.布局屬性中還有cell的索引
3.此方法是用來(lái)計(jì)算所有cell的frame及索引,而且每一個(gè)cell只計(jì)算一次,計(jì)算完成之后就不會(huì)再重復(fù)計(jì)算
4.通過(guò)修改每一個(gè)cell對(duì)應(yīng)的布局屬性可以直接修改cell的frame,所以推理我們可以自己來(lái)計(jì)算每一個(gè)cell的frame最后把每一個(gè)cell對(duì)應(yīng)的布局屬性添加到數(shù)組中最終用此方法返回我們自己算好的frame應(yīng)該可以實(shí)現(xiàn)瀑布流效果
// 在數(shù)組的最后還要計(jì)算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;
}
瀑布流的規(guī)則:圖片定寬而不定高;必須拿到圖片的真實(shí)寬、高,以保證圖片按正常比例顯示,保證美觀性。
每一行圖片顯示完之后,下一行圖片顯示的順序是:從高度最矮的那一列開(kāi)始顯示;所以最好定義一個(gè)可變的數(shù)組來(lái)動(dòng)態(tài)的保存每一列的高。
上拉刷新加載圖片:
調(diào)用UIScrollerView的代理方法:屏幕正在滾動(dòng)中都會(huì)調(diào)用此方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// 如果footerView還沒(méi)有出來(lái)以及正在加載中都不要再去重復(fù)加載更多
if (self.footerView == nil || self.footerView.activity.isAnimating == YES) return;
// 當(dāng)footerView完全顯示之后再加加載更多"而不是footerView一出來(lái)就去加載更多
if (self.collectionView.contentOffset.y + self.collectionView.bounds.size.height > CGRectGetMaxY(self.footerView.frame) ) {
// 正在加載時(shí)先讓花花轉(zhuǎn)起來(lái)
[self.footerView.activity startAnimating];
// 延遲去模擬網(wǎng)絡(luò)加載
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 1.給模型數(shù)組中添加更多數(shù)據(jù)
[self loadMoreData];
// 2.讓數(shù)據(jù)源方法重新執(zhí)行
[self.collectionView reloadData];
// 3.讓花花停止轉(zhuǎn)
[self.footerView.activity stopAnimating];
// 4.把footerView屬性設(shè)置為nil
self.footerView = nil;
});
}
}