Files
peko-ios/YuMi/Modules/YMMessage/View/Session/View/MSSessionScrollingItemFlowLayout.m
2024-05-11 19:41:06 +08:00

139 lines
5.2 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// MSSessionScrollingItemFlowLayout.m
// YuMi
//
// Created by duoban on 2024/5/11.
//
#import "MSSessionScrollingItemFlowLayout.h"
@interface MSSessionScrollingItemFlowLayout()
@property (nonatomic, strong) NSMutableArray *itemAttributes; // 存放每个cell的布局属性
// 垂直瀑布流相关属性
@property (nonatomic, strong) NSMutableArray *columnsHeights; // 每一列的高度(count=多少列)
@property (nonatomic, assign) CGFloat maxHeight; // 最长列的高度(最大高度)
@property (nonatomic, assign) CGFloat minHeight; // 最短列的高度(最低高度)
@property (nonatomic, assign) NSInteger minIndex; // 最短列的下标
@property (nonatomic, assign) NSInteger maxIndex; // 最长列的下标
// 水平瀑布流相关属性
@property (nonatomic, strong) NSMutableArray *columnsWidths; // 每一行的宽度(count不确定)
@property (nonatomic, assign) NSInteger tempItemX; // 临时x : 用来计算每个cell的x值
@property (nonatomic, assign) NSInteger maxRowIndex; //最大行
@end
@implementation MSSessionScrollingItemFlowLayout
//
#pragma mark -- 系统内部方法
/**
* 重写父类布局
*/
- (void)prepareLayout {
[super prepareLayout];
// (水平瀑布流时)重置最大行
if ((self.type == MSDirectionTypeHorizontalType)) {
self.maxRowIndex = 0;
}
if (self.type == MSDirectionTypeVerticalType) {
// (垂直瀑布流时)重置每一列的高度
[self.columnsHeights removeAllObjects];
for (NSUInteger i = 0; i < self.numberOfColumns; i++) {
[self.columnsHeights addObject:@(self.insets.top)];
}
}
// 计算所有cell的布局属性
[self.itemAttributes removeAllObjects];
NSUInteger itemCount = [self.collectionView numberOfItemsInSection:0];
self.tempItemX = self.insets.left;
for (NSUInteger i = 0; i < itemCount; ++i) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
if (self.type == MSDirectionTypeVerticalType) {
[self setVerticalFrame:indexPath];
}else if ((self.type == MSDirectionTypeHorizontalType)){
[self setHorizontalFrame:indexPath];
}
}
}
/**
* 水平瀑布设置每一个attrs的frame并加入数组中
*/
- (void)setHorizontalFrame:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGFloat w = [self.itemWidths[indexPath.item] floatValue];
CGFloat width = w + self.columnGap;
CGFloat h = (self.rowHeight == 0) ? 100 : self.rowHeight;
/**
* 如果当前的x值+当前cell的宽度 超出了 屏幕宽度,那么就要换行了。
* 换行操作 : 最大行+1tempItemX重置为10(self.insets.left)。
*/
if (self.tempItemX + w > [UIScreen mainScreen].bounds.size.width) {
self.maxRowIndex++;
self.tempItemX = self.insets.left;
}
CGFloat x = self.tempItemX;
CGFloat y = self.insets.top + self.maxRowIndex * (h + self.rowGap);
attrs.frame = CGRectMake(x, y, w, h);
/**
* 注1.cell的宽度和高度算起来比较简单 : 宽度由外部传进来高度固定为rowHeight(默认为100)。
* 2.cell的x : 通过tempItemX算好了。
* 3.cell的y : minHeight最短列的高度也就是最低高度作为当前cell的起始y当然要加上行之间的间隙。
*/
NSLog(@"%@",NSStringFromCGRect(attrs.frame));
[self.itemAttributes addObject:attrs];
self.tempItemX += width;
}
/**
* 垂直瀑布设置每一个attrs的frame并加入数组中
*/
- (void)setVerticalFrame:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
// cell的frame
CGFloat w = self.itemWidth;
CGFloat h = [self.itemHeights[indexPath.item] floatValue];
CGFloat x = self.insets.left + self.minIndex * (w + self.columnGap);
CGFloat y = self.minHeight + self.rowGap;
attrs.frame = CGRectMake(x, y, w, h);
/**
* 注1.cell的宽度和高度算起来比较简单 : 宽度固定(itemWidth已经算好),高度由外部传进来
* 2.cell的x : minIndex最短列作为当前列。
* 3.cell的y : minHeight最短列的高度也就是最低高度作为当前cell的起始y当然要加上行之间的间隙。
*/
// 更新数组中的最大高度
self.columnsHeights[self.minIndex] = @(CGRectGetMaxY(attrs.frame));
NSLog(@"%@",NSStringFromCGRect(attrs.frame));
[self.itemAttributes addObject:attrs];
}
/**
* 返回collectionView的尺寸
*/
- (CGSize)collectionViewContentSize {
CGFloat height;
if (self.type == MSDirectionTypeHorizontalType) {
CGFloat rowHeight = (self.rowHeight == 0) ? 100 : self.rowHeight;
height = self.insets.top + (self.maxRowIndex+1) * (rowHeight + self.rowGap);
}else {
height = self.maxHeight;
}
return CGSizeMake(self.collectionView.frame.size.width, height);
}
/**
* 所有元素比如cell、补充控件、装饰控件的布局属性
*/
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
return self.itemAttributes;
}
@end