澳门威利斯人_威利斯人娱乐「手机版」

来自 威利斯人娱乐 2020-05-08 17:15 的文章
当前位置: 澳门威利斯人 > 威利斯人娱乐 > 正文

UICollectionView的瀑布流,从零开始UICollectionView

###

关于UICollectionView,苹果是如此解释的:管理数据项的平稳聚焦,并行使可定制的结构彰显它们。在iOS中最简便易行的UICollectionView便是GirdView,能够以多列的办法将数据开展体现。标准的UICollectionView包涵以下3个部分,他们都以UIView的子类:

前言

对于众多的等级次序以来,瀑布流是极度首要的一个UI效果。在此处不根究瀑布流的产出历史,只追求它的落到实处。作者尽恐怕讲得详细。
事实上只要深远的去追查UICollectionView就能够意识,它只但是是四个基于UIScrollView的投入重用机制的冲天精心的包装控件,全数有关UICollectionView结构的奥妙,都在UICollectionViewLayout的里面。
鉴于那是三个抽象类无法一向运用,常常我们会创立和利用它的子类。

想必大家早就对网络古板的相片布局方式袖手观望了,这种行列明显的构造固然对顾客来讲精练,可是短时间的选用难免会发生审美疲劳。以后英特网流行一种叫做“瀑布流”的肖像构造样式,这种行与列参差不齐的场馆包车型地铁确给顾客别开生面的以为

  • Cell:用于突显内容的着入眼,能够定制其尺寸和剧情。
  • Supplementary view :用于扩张视图,和UITableView里面包车型地铁Header和Footer的功力相似。
  • Decoration View : 用于装饰视图,是种种section的背景.

    图片 1标准UICollectionView的构成

原理:全部的瀑布流都应该依照已知的宽高比例,通过定位的宽(高)来计量其它叁个高(宽)。

效果图

图片 2瀑布流

1.开撸之 UICollectionViewLayout。

1.1 大家先是要写贰个连任自UICollectionViewLayout的子类,本Demo中为@interface BJWaterfullLayout : UICollectionViewLayout

兑现瀑布流的三种艺术

  • 率先种: 使用两个UIScrollView下面放着七个UITabelView然后在检查制止UITabelView的滑动,只同意专擅的UIScrollView滑动
  • 第两种:只是用UIScrollView,但是正如多的时候 我们也是急需援用,这个时候大家要求本身 设计出一套重用机制。
  • 其二种:(最简易 UICollectionViewLayout卡塔尔 在UICollectionView出来以往大家平常都以运用这种方法来达成瀑布流,因为大家无需规划重用机制。

我今天我们讲的就是第三种方式来实现瀑布流福寿无疆思路: 正是每一个cell都会加到最短的中度上

  • UICollectionViewLayout的落到实处大家先创建八个无冕于UICollectionViewLayout WaterLayout
  • .h 文件
#import <UIKit/UIKit.h>//前置声明@class XMGWaterflowLayout;//代理@protocol XMGWaterflowLayoutDelegate <NSObject>@required//必须实现的代理方法- waterflowLayout:(XMGWaterflowLayout *)waterflowLayout heightForItemAtIndex:(NSUInteger)index itemWidth:itemWidth;//可实现可不实现的代理方法 这个是通过代理调用的接口 也可以 通过set方法来实现接口@optional- columnCountInWaterflowLayout:(XMGWaterflowLayout *)waterflowLayout;- columnMarginInWaterflowLayout:(XMGWaterflowLayout *)waterflowLayout;- rowMarginInWaterflowLayout:(XMGWaterflowLayout *)waterflowLayout;- (UIEdgeInsets)edgeInsetsInWaterflowLayout:(XMGWaterflowLayout *)waterflowLayout;@end@interface XMGWaterflowLayout : UICollectionViewLayout/** 代理 */@property (nonatomic, weak) id<XMGWaterflowLayoutDelegate> delegate;@end
  • 在WaterLayout的.m文件
/** 默认的列数 */static const NSInteger XMGDefaultColumnCount = 3;/** 每一列之间的间距 */static const CGFloat XMGDefaultColumnMargin = 10;/** 每一行之间的间距 */static const CGFloat XMGDefaultRowMargin = 10;/** 边缘间距 */static const UIEdgeInsets XMGDefaultEdgeInsets = {10, 10, 10, 10};
  • 在.m的@interface classion中
/** 存放所有cell的布局属性 */@property (nonatomic, strong) NSMutableArray *attrsArray;/** 存放所有列的当前高度 */@property (nonatomic, strong) NSMutableArray *columnHeights;/** 内容的高度 */@property (nonatomic, assign) CGFloat contentHeight;//这里方法为了简化 数据处理(通过getter方法来实现)- rowMargin;- columnMargin;- (NSInteger)columnCount;- (UIEdgeInsets)edgeInsets;
  • 那一个getter方法的得以实现 其余的同理
#pragma mark - 常见数据处理- rowMargin{//如果delegate方法没有实现的话就使用代理方法 否则就使用默认值 然后通过getter方法来判断 来简化代码 if ([self.delegate respondsToSelector:@selector(rowMarginInWaterflowLayout:)]) { return [self.delegate rowMarginInWaterflowLayout:self]; } else { return XMGDefaultRowMargin; }}
  • .m文件中的瀑布流首要的兑现
/** * 初始化 */- prepareLayout{ [super prepareLayout]; //先初始化内容的高度为0 self.contentHeight = 0; // 清除以前计算的所有高度 [self.columnHeights removeAllObjects]; //先初始化 存放所有列的当前高度 3个值 for (NSInteger i = 0; i < self.columnCount; i  ) { [self.columnHeights addObject:@(self.edgeInsets.top)]; } // 清除之前所有的布局属性 [self.attrsArray removeAllObjects]; // 开始创建每一个cell对应的布局属性 NSInteger count = [self.collectionView numberOfItemsInSection:0]; for (NSInteger i = 0; i < count; i  ) { // 创建位置 NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0]; // 获取indexPath位置cell对应的布局属性 UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath]; [self.attrsArray addObject:attrs]; }}/** * 决定cell的排布 */- (NSArray *)layoutAttributesForElementsInRect:rect{ return self.attrsArray;}/** * 返回indexPath位置cell对应的布局属性 */- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{ // 创建布局属性 UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; // collectionView的宽度 CGFloat collectionViewW = self.collectionView.frame.size.width; // 设置布局属性的frame CGFloat w = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin) / self.columnCount; CGFloat h = [self.delegate waterflowLayout:self heightForItemAtIndex:indexPath.item itemWidth:w]; // 找出高度最短的那一列 //找出来最短后 就把下一个cell 添加到低下 NSInteger destColumn = 0; CGFloat minColumnHeight = [self.columnHeights[0] doubleValue]; for (NSInteger i = 1; i < self.columnCount; i  ) { // 取得第i列的高度 CGFloat columnHeight = [self.columnHeights[i] doubleValue]; if (minColumnHeight > columnHeight) { minColumnHeight = columnHeight; destColumn = i; } } CGFloat x = self.edgeInsets.left   destColumn * (w   self.columnMargin); CGFloat y = minColumnHeight; if (y != self.edgeInsets.top) { y  = self.rowMargin; } attrs.frame = CGRectMake(x, y, w, h); // 更新最短那列的高度 self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame)); // 记录内容的高度 CGFloat columnHeight = [self.columnHeights[destColumn] doubleValue]; //找出最高的高度 if (self.contentHeight < columnHeight) { self.contentHeight = columnHeight; } return attrs;}/*! * 返回值就是这个CollectionView的contensize 因为CollectionView也是ScrollView的子类 */- collectionViewContentSize{// CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];// for (NSInteger i = 1; i < self.columnCount; i  ) {// // 取得第i列的高度// CGFloat columnHeight = [self.columnHeights[i] doubleValue];// // if (maxColumnHeight < columnHeight) {// maxColumnHeight = columnHeight;// }// } return CGSizeMake(0, self.contentHeight   self.edgeInsets.bottom);}
  • 在ViewController中的使用
 // 创建布局 XMGWaterflowLayout *layout = [[XMGWaterflowLayout alloc] init]; layout.delegate = self;//然后继承代理实现代理方法#pragma mark - <WaterLayoutDelegate>//返回每个cell的高度- waterflowLayout:(XMGWaterflowLayout *)waterflowLayout heightForItemAtIndex:(NSUInteger)index itemWidth:itemWidth{ XMGShop *shop = self.shops[index]; return itemWidth * shop.h / shop.w;}//每行的最小距离- rowMarginInWaterflowLayout:(XMGWaterflowLayout *)waterflowLayout{ return 10;}//有多少列- columnCountInWaterflowLayout:(XMGWaterflowLayout *)waterflowLayout{ if (self.shops.count <= 50) return 2; return 3;}//内边距- (UIEdgeInsets)edgeInsetsInWaterflowLayout:(XMGWaterflowLayout *)waterflowLayout{ return UIEdgeInsetsMake(10, 20, 30, 100);}

GitHub-->德姆oUIcollectionViewLayout的布局详明

上一篇SquareLayout方形构造

  • 相同点:
    • 皆以继续自UIScrollView,帮忙滚动。
    • 都扶植数据单元格的选用机制。
    • 都以由此代办方法和数据源方法来兑现调整和显示。
  • 不同点:
    • UICollectionView的section里面包车型地铁数额单元叫做item,UITableView的称之为cell
    • UICollectionView的布局使用UICollectionViewLayou或许其子类UICollectionViewFlowLayout和易于达成自定义构造。
鉴于我们是纵向瀑布流,宽度是定点的,根据宽高比动态变化中度。

本文由澳门威利斯人发布于威利斯人娱乐,转载请注明出处:UICollectionView的瀑布流,从零开始UICollectionView

关键词: 澳门威利斯人 IOS 详解 瀑布 UICollection