封装自定义瀑布流,实现原理
来源:互联网 发布:数据库中范式的作用 编辑:程序博客网 时间:2024/05/17 08:12
继承UICollectionViewLayout
@interface WaterPullLayout : UICollectionViewLayout
需要两个数组来保存每个item的属性和每列的总高度
@interface WaterPullLayout (){ /** * 保存每个item的属性 */ NSMutableArray *_itemAttributes; /** * 保存每列的高度 */ NSMutableArray *_columnHeights;}
.m实现必须重写四个方法:
-//对item布局,reloadData会触发- (void)prepareLayout- //返回指定区域的item的属性对象数组- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect-//返回指定indexPath的item的属性对象- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath-//collectionView的contentSize- (CGSize)collectionViewContentSize
-#import 《UIKit/UIKit.h>
@protocol WaterPullLayoutDelegate
@required
- (CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout )collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
@end
@interface WaterPullLayout : UICollectionViewLayout
/**
* 列数
*/
@property (nonatomic) NSInteger columnCount;
/**
* 距离上下左右的距离
*/
@property (nonatomic) UIEdgeInsets sectionInsets;
/**
* 两个cell的水平方向的空隙
*/
@property (nonatomic) CGFloat horizontalSpace;
/**
* 两个cell的垂直方向的空隙
*/
@property (nonatomic) CGFloat verticalSpace;
@end
#import "WaterPullLayout.h"@interface WaterPullLayout (){ /** * 保存每个cell的属性 */ NSMutableArray *_itemAttributes; /** * 保存每列的高度 */ NSMutableArray *_columnHeights;}@property (nonatomic, weak) id<WaterPullLayoutDelegate> delegate;@end@implementation WaterPullLayout- (instancetype)init{ self = [super init]; if (self) { //默认2列 _columnCount = 2; _horizontalSpace = 10; _verticalSpace = 10; _sectionInsets = UIEdgeInsetsZero; } return self;}/** * 返回高度最大的列的索引 */- (NSInteger)maxHeightColumnIndex{ __block NSInteger index = 0; __block CGFloat maxValue = 0; [_columnHeights enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { //如果从数组里面取出的元素比现有最大值还大,这个元素就是最大值 if ([obj floatValue] > maxValue) { //替换最大值 maxValue = [obj floatValue]; //保存最大值的索引 index = idx; } }]; return index;}/** * @return 返回高度最小的列的索引 */- (NSInteger)minHeightColumnIndex{ __block NSInteger index = 0; __block CGFloat minValue = MAXFLOAT; [_columnHeights enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { //如果从数组里面取出的元素比现有最小值还小,这个元素就是最小值 if ([obj floatValue] < minValue) { //替换最小值 minValue = [obj floatValue]; //保存最小值的索引 index = idx; } }]; return index;}//对item布局,reloadData会触发- (void)prepareLayout{ [super prepareLayout]; self.delegate = (id<WaterPullLayoutDelegate>)self.collectionView.delegate; //初始化数组 _itemAttributes = [NSMutableArray array]; _columnHeights = [NSMutableArray array]; //初始化默认高度 for (int i = 0; i < self.columnCount; i++) { //每列的高度初始化都是0 _columnHeights[i] = @(0); } //item的宽度 =(collectionView的宽 - 左边距 - 右边距 - item间的水平间隙 )/ 列数 CGFloat itemWidth = (self.collectionView.frame.size.width - self.sectionInsets.left - self.sectionInsets.right - (self.columnCount - 1)*self.horizontalSpace)/self.columnCount; //计算每个item的位置坐标(只考虑一个组的情况) //[self.collectionView numberOfItemsInSection:0]返回指定组的item个数 for (int i = 0; i < [self.collectionView numberOfItemsInSection:0]; i++) { //获取item大小(调用collectionView的代理方法) CGSize size = [self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]]; //item的高度 CGFloat itemHeight; //item的x坐标 CGFloat xOffset; //item的y坐标 CGFloat yOffset; //现在图片的高度 /* 原始H X ---- = ----- ===> X = 原始H*现在W/原始W 原始W 现在W */ itemHeight = size.height * itemWidth / size.width; //获取列的高度的最小值索引 NSInteger minIndex = [self minHeightColumnIndex]; NSLog(@"%ld",minIndex); //item的x坐标 = 与左边间距 + 最小高度索引值*(item宽 + item间水平间隙) xOffset = self.sectionInsets.left + minIndex*(itemWidth+self.horizontalSpace); //item的y坐标 = 最小高度 + (item个数如果小于列数)?与顶部间距 :item间的垂直间隙 yOffset = [_columnHeights[minIndex] floatValue] + ((i < self.columnCount) ? self.sectionInsets.top : self.verticalSpace); //item的frame CGRect itemFrame = CGRectMake(xOffset, yOffset, itemWidth, itemHeight); //属性 UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:0]]; attribute.frame = itemFrame; //添加到数组中 [_itemAttributes addObject:attribute]; //修改当前列的高度 _columnHeights[minIndex] = @(CGRectGetMaxY(itemFrame)); }}/** * 返回指定区域的cell的属性对象数组 * * @param rect <#rect description#> * * @return <#return value description#> */- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{ return _itemAttributes;}/** * 返回指定indexPath的item的属性对象 * * @param indexPath <#indexPath description#> */- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{ return _itemAttributes[indexPath.item];}/** * collectionView的contentSize */- (CGSize)collectionViewContentSize{ //取最大值的索引 NSInteger maxIndex = [self maxHeightColumnIndex]; //返回collectionView的contentSize return CGSizeMake(self.collectionView.frame.size.width, [_columnHeights[maxIndex] floatValue] + self.sectionInsets.bottom);}@end
0 0
- 封装自定义瀑布流,实现原理
- 自定义UICollectionViewLayout实现瀑布流
- 自定义collocationViewLayout实现瀑布流
- PinterestLikeAdapterView 瀑布流实现原理
- 瀑布流PinterestLikeAdapterView实现原理
- IOS瀑布流实现原理
- 瀑布流的实现原理
- 自定义ViewGroup实现瀑布流样式
- 自定义ViewGroup实现瀑布流效果
- 自定义layout实现瀑布流_UICollectionView
- 自定义UICollectionViewLayout—实现瀑布流效果
- 瀑布流(自定义布局实现)
- swift瀑布流自定义布局实现
- RecyclerView自定义LayoutManager实现横向瀑布流
- iOS自定义UICollectionViewLayout布局实现瀑布流
- android瀑布流简单实现原理
- 瀑布流的实现原理与实例
- 瀑布流封装
- jerror.h文件找不到及出错的原因
- 八皇后问题-C语言
- PostgreSQL主备流复制机制详解
- 随笔
- 关于前端的一些东西--记住了一些,闲时再看看
- 封装自定义瀑布流,实现原理
- 调查应用的RAM使用情况
- C++:继承1(矩形右上角坐标)
- 如何安装系统认证签名过的APK
- iOS中的图形
- SpringSessionRedis配置及发现的问题
- JAVA多线程之(wait notify)
- 快速简单的定制一个时间轴布局(LinearLayout)
- 欢迎使用CSDN-markdown编辑器