【iOS】UICollectionView的基本使用
创始人
2024-02-20 06:13:57
0

UICollectionView是与UITableView相似的控件,不过它的布局更加自由。

与UITableView的不同

tableViewcollectionView
初始化需要指定布局style。需要指定一个布局类。
子视图布局一行代表一个cell,布局只需要考虑行高。无视行列限制,一个item对应一个cell,由布局类来指定视图位置。
重用机制针对cell,且非强制,某种cell也可以在非注册下使用。针对所有子视图,且强制,必须注册才能使用。
重用机制调用初始化方法在tableView的重用机制里,对于注册了的类,会在需要创建该类的对象的时候自动调用该类的initWithStyle:reuseIdentifier:方法。在collectionView的重用机制里,对于注册了的类,会在需要该类的对象的时候自动调用该类的initWithFrame:方法。

以上摘自:https://blog.csdn.net/ohyeahhhh/article/details/51222590

UICollectionViewLayout与UICollectionViewFlowLayout简介

UICollectionViewLayout是一个layout对象,UICollectionView几乎所有的显示效果都由UICollectionViewLayout负责。

UICollectionViewFlowLayout是继承自UICollectionViewLayout的,是官方实现的流水布局效果,是一种非常经典的布局效果,应该也是我们最常用的。

UICollectionViewFlowLayout的一些基本属性:

  1. itemSize 每个item的大小;
  2. minimumLineSpacing 每行最小间距;
  3. minimumInteritemSpacing 每列最小间距;
  4. sectionInset 每个section的边距;
  5. scrollDirection 元素滚动方向。

流水式布局:
流布局是苹果预先定义的布局,这种布局就好比流水一样,将一个个cell按顺序排列。出来的效果跟网格差不多。

简单使用UICollectionView布置简单九宫格视图

  1. 初始化UICollecctionViewFlowLayout与UICollectionView。设置UICollectionView的delegate和dataSource。注意cell必须被注册才能使用。
- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc] init];flowLayout.itemSize = CGSizeMake(100, 100);flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;flowLayout.minimumLineSpacing = 20;flowLayout.minimumInteritemSpacing = 20;flowLayout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];self.collectionView.delegate = self;self.collectionView.dataSource = self;[self.view addSubview:self.collectionView];}
  1. 完成协议方法(基本与tableView一致)。
- (NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 1;
}- (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return 10;
}- (UICollectionViewCell*) collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {UICollectionViewCell* cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];cell.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];return cell;
}

效果:
在这里插入图片描述

自定义layout实现瀑布流布局

先放效果图:
在这里插入图片描述

UICollectionViewLayoutAttributes

首先介绍UICollectionViewLayoutAttributes类,它保存了每一个cell的大小位置等属性,每一个cell都有一个对应的UICollectionViewLayoutAttributes。UICollectionViewLayout正是通过它保存的信息进行布局。

涉及的方法

-(void)prepareLayout;
-(CGSize)collectionViewContentSize;
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;

  • -(void)prepareLayout; 在该方法用于计算各cell的位置和大小,并把它们封装成一个UICollectionViewLayoutAttributes。
  • -(CGSize)collectionViewContentSize; 该方法返回ContentView的大小。
  • -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect; 该方法返回包含所有子视图的UICollectionViewLayoutAttributes对象的数组。

具体步骤

  1. 创建一个继承自UICollectionViewFlowLayout的类,添加一个itemCount。
    Mylayout.h
#import NS_ASSUME_NONNULL_BEGIN@interface MyLayout : UICollectionViewFlowLayout@property (nonatomic, assign) int itemCount;@endNS_ASSUME_NONNULL_END
  1. 在实现部分添加一个NSMutableArray的成员变量,用于储存所有子视图的UICollectionViewLayoutAttributes对象。
  2. 重写-(void)prepareLayout;在该方法内计算每个cell的位置和大小,并把它们封装成一个UICollectionViewLayoutAttributes对象,添加到专门保存UICollectionViewLayoutAttributes对象的成员变量中。下面是代码:
- (void) prepareLayout {attributeArray = [[NSMutableArray alloc] init];[super prepareLayout];// 计算每个item的宽度float WIDTH = ([UIScreen mainScreen].bounds.size.width - self.minimumInteritemSpacing - self.sectionInset.left - self.sectionInset.right) / 2;// 这个数组用于储存当前左右两列瀑布流的长度,保证新的item添加在短的一边下面。CGFloat colHight[2] = {0};// 循环计算每个item的位置大小for (int i = 0; i < self.itemCount; i++) {// 获取indexNSIndexPath* index = [NSIndexPath indexPathForItem:i inSection:0];// 根据index创建attributes对象UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:index];// 随机一个高度,在40-190之间CGFloat hight = arc4random()%150 + 40;// 标记最短的列int width = 0;// 将新的item的高度加到最短的列下if (colHight[0] < colHight[1]) {colHight[0] = colHight[0] + hight + self.minimumLineSpacing;width = 0;} else {colHight[1] = colHight[1] + hight + self.minimumLineSpacing;width = 1;}// 将改item的位置和大小封装成UICollectionViewLayoutAttributes对象attributes.frame = CGRectMake(self.sectionInset.left + (self.minimumInteritemSpacing + WIDTH) * width, colHight[width] - hight - self.minimumLineSpacing, WIDTH, hight);// 保存UICollectionViewLayoutAttributes对象[attributeArray addObject:attributes];}// 通过预设itemSize的大小保证滑动范围的正确(取一个高度上的平均值),也可以通过重写`-(CGSize)collectionViewContentSize; `方法完成if (colHight[0] > colHight[1]) {self.itemSize = CGSizeMake(WIDTH, ((colHight[0] - self.sectionInset.top) * 2 / self.itemCount - self.minimumLineSpacing));} else {self.itemSize = CGSizeMake(WIDTH, ((colHight[1] - self.sectionInset.top) * 2 / self.itemCount - self.minimumLineSpacing));}}
  1. 重写-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect; 方法返回包含所有子视图的UICollectionViewLayoutAttributes对象的数组。
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {return attributeArray;
}
  1. 初始化CollectionView。
- (void) getMyLayout {MyLayout* layout = [[MyLayout alloc] init];layout.scrollDirection = UICollectionViewScrollDirectionVertical;layout.itemCount = 100;layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];self.collectionView.delegate = self;self.collectionView.dataSource = self;[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];[self.view addSubview:self.collectionView];
}
  1. 完成协议方法。
- (NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 1;
}- (NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return 100;
}- (UICollectionViewCell*) collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {UICollectionViewCell* cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];cell.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];return cell;
}

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...