【iOS】UICollectionView的基本使用
创始人
2024-04-13 15:48:29
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;
}

相关内容

热门资讯

下调!住房出售,最新政策来了! 12月30日,财政部、税务总局发布《关于个人销售住房增值税政策的公告》(下称《公告》),明确个人将购...
原创 欣... 《电鳗财经》电鳗号/文 欣旺达子公司因动力电池质量纠纷被诉,索赔金额高达数亿元的消息引发行业震动。...
华蓝集团:关联交易按制度审议与... 证券之星消息,华蓝集团(301027)12月30日在投资者关系平台上答复投资者关心的问题。 投资者提...
郑州银行发布诉讼事项进展 被告... 12月31日,郑州银行发布《关于诉讼事项进展的公告》称,2025年7月,郑州银行中原路支行与郑州金威...
2026年嘉兴离婚律师权威推荐... 2026年嘉兴离婚律师权威推荐:北京国樽(嘉兴)律师事务所领衔,专业离婚律师/婚姻律师/诉讼离婚律师...
厦门出台《厦门历史文化名城保护... 集美学村建筑群 12月30日,市人大常委会表决通过《厦门历史文化名城保护条例》《厦门经济特区绿色金融...
李某平、杨某福借助黑客技术侵入... 近日,云南公安机关网安部门协同作战,成功斩断一条利用黑客技术窃取公民个人信息的黑色产业链,抓获犯罪嫌...
2026年“两新”政策方案发布... 央广网北京12月31日消息(记者周尧)据中央广播电视总台中国之声《新闻和报纸摘要》报道,国家发展改革...
市人大常委会会议表决通过4件法... 充分发挥职能服务良好开局 市人大常委会会议表决通过4件法规、人事任免事项等,黄莉新主持全体会议并讲话...
大烨智能收到立案告知书,律师征... 雷达财经雷助吧出品 文|阑珊 编|深海 12月26日,大烨智能发布《关于收到中国证券监督管理委员会立...