需求
需求
頁面顯示最少0行最多兩行王浴,超過兩行水平方向分頁顯示拥知。
效果
collectionViewGIF.gif
分析
常用功能中應(yīng)用個數(shù)是不固定的岩饼,高度也是不固定的,過多時(shí)橫向分頁籍茧。
選擇UICollectionView控件來實(shí)現(xiàn),使用UICollectionViewFlowLayout布局寞冯,設(shè)置滾動方向?yàn)樗健?/p>
問題
使用UICollectionViewFlowLayout進(jìn)行布局后發(fā)現(xiàn)頁面顯示為
錯誤布局
而我們期望的是
正確布局
解決方法
核心代碼
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
NSInteger item = indexPath.item;
/*
0 2 4 ---\ 0 1 2
1 3 5 ---/ 3 4 5 計(jì)算轉(zhuǎn)換后對應(yīng)的item 原來'4'的item為4,轉(zhuǎn)換后為3
*/
NSInteger page = item / (self.itemCountPerRow * self.maxRowCount);
// 計(jì)算目標(biāo)item的位置 x 橫向偏移 y 豎向偏移
NSUInteger x = item % self.itemCountPerRow + page * self.itemCountPerRow;
NSUInteger y = item / self.itemCountPerRow - page * self.rowCount;
// 根據(jù)偏移量計(jì)算item
NSInteger newItem = x * self.rowCount + y;
NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:newItem inSection:indexPath.section];
UICollectionViewLayoutAttributes *newAttributes = [super layoutAttributesForItemAtIndexPath:newIndexPath];
newAttributes.indexPath = indexPath;
return newAttributes;
}
UICollectionViewLayoutAttributes是管理collectionView中item的布局相關(guān)屬性的布局對象。
我們這里通過重新設(shè)置Item對應(yīng)UICollectionViewLayoutAttributes的indexPath來達(dá)到我們想要的效果吮龄,需要注意的是為了防止出現(xiàn)數(shù)組越界的情況這里做了使每一行Item都是“滿”的處理(即Item的個數(shù)為itemCountPerRow的整數(shù)倍)。
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
NSInteger itemCount;
if (self.dataArray.count == 0) {
itemCount = 0;
} else if (self.dataArray.count / (kMaxRowCount * kItemCountPerRow) > 1) {
itemCount = kMaxRowCount * kItemCountPerRow * ceilf(self.dataArray.count / (kMaxRowCount * kItemCountPerRow));
} else {
itemCount = ceilf(self.dataArray.count / kItemCountPerRow) * kItemCountPerRow;
}
return itemCount;
}
占位
為了更好的體現(xiàn)螟蝙,這里未對label背景顏色進(jìn)行透明處理,我們可以從圖中看出6、7的位置實(shí)際是返回了UICollectionViewCell胰默。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewLabelCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[CollectionViewLabelCell description] forIndexPath:indexPath];
if (indexPath.item < self.dataArray.count) {
cell.backgroundColor = [UIColor lightGrayColor];
cell.labelTitle.text = self.dataArray[indexPath.item];
}else{
cell.backgroundColor = [UIColor clearColor];
cell.labelTitle.text = @"";
}
return cell;
}
demo地址:https://github.com/ABChe/HorizontallyPageableFlowLayout