iOS自定義collectionViewLayout
iOS開發(fā)collectionView也算用的比較廣泛了缝彬,但是系統(tǒng)的collectionViewLayout有時候不能夠滿足開發(fā)需求,比如小紅書那種瀑布流没佑。這里講一講自定義collectionViewLayout,需要重寫四個方法
- -(void)prepareLayout
2.-(CGSize)collectionViewContentSize;
3.-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
4.-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
直接上代碼
@interface SSCollectionViewLayout()
/** cell height arrays */
@property(nonatomic,strong)NSArray *cellHeightArrays;
/** attributes arrays */
@property(nonatomic,strong)NSMutableArray *attributesArrays;
/** cell array */
@property(nonatomic,strong)NSMutableArray *tempAttributesArrays;
@end
@implementation SSCollectionViewLayout
-(instancetype)initWithArrays:(NSArray *)cellHeightArrays
{
if (self = [super init]) {
self.cellHeightArrays = cellHeightArrays;
}
return self;
}
//自定義layout需要重寫這些方法
-(void)prepareLayout
{
[super prepareLayout];
[self.attributesArrays removeAllObjects];
[self.tempAttributesArrays removeAllObjects];
//獲取當前collectionView對應區(qū)的item
//獲取senction全部個數(shù)
NSInteger count = [self.collectionView numberOfItemsInSection:0];
for (int i=0; i < count; i++) {
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow: i inSection:0]];
[self.attributesArrays addObject:attributes];
}
}
//返回collectionView的內(nèi)容的尺寸
-(CGSize)collectionViewContentSize
{
CGFloat maxContentHeight = CGRectGetMaxY([[self.tempAttributesArrays firstObject] frame]);
for (UICollectionViewLayoutAttributes *attributes in self.tempAttributesArrays) {
if (maxContentHeight < attributes.frame.size.height) {
maxContentHeight = CGRectGetMaxY(attributes.frame);
}
}
return CGSizeMake(self.collectionView.bounds.size.width, maxContentHeight);
}
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
return self.attributesArrays;
}
///返回對應于indexPath的位置的cell的布局屬性,返回指定indexPath的item的布局信息。子類必須重載該方法,該方法只能為cell提供布局信息,不能為補充視圖和裝飾視圖提供符匾。
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGFloat itemWidth = (self.collectionView.bounds.size.width - (10 + 10 + 10 * 2))/3;
CGFloat itemHeight = [self.cellHeightArrays[indexPath.row] floatValue];
//在這里用上cellArrays了,橫排最多顯示3個
if (self.tempAttributesArrays.count < 3) {//設(shè)置第一排rect
[self.tempAttributesArrays addObject:attributes];
NSLog(@"%ld",self.tempAttributesArrays.count);
CGRect rect = CGRectMake(10 +( itemWidth + 10) * (self.tempAttributesArrays.count - 1), 10, itemWidth, itemHeight);
attributes.frame = rect;
}else{
UICollectionViewLayoutAttributes *fristAttributes = [self.tempAttributesArrays firstObject];
CGFloat minY = CGRectGetMaxY(fristAttributes.frame);
CGFloat Y = minY;
NSInteger index = 0;
CGRect itemFrame = CGRectMake(fristAttributes.frame.origin.x, CGRectGetMaxY(fristAttributes.frame) + 10, itemWidth, itemHeight);
for (UICollectionViewLayoutAttributes *attri in self.tempAttributesArrays) {
if (minY > CGRectGetMaxY(attri.frame)) {
minY = CGRectGetMaxY(attri.frame);
Y = minY;
itemFrame = CGRectMake(attri.frame.origin.x, Y + 10, itemWidth, itemHeight);
NSInteger currentIndex = [self.tempAttributesArrays indexOfObject:attri];
index = currentIndex;
}
}
attributes.frame = itemFrame;
[self.tempAttributesArrays replaceObjectAtIndex:index withObject:attributes];
}
return attributes;
}
這里我們就實現(xiàn)了一個自定義layout,例子顯示橫屏3個item瘩例,高度通過動態(tài)傳過來啊胶,實際開發(fā)中,需要跟后臺商量垛贤,返回cell高度焰坪。