文章目录
- 前言
- 实现九宫格布局
- layout中常用的一些属性
- 参差瀑布流的实现
- 声明自定义子类
前言
UICollectionView
是iOS开发中一种功能强大的视图容器,用于展示可滚动且布局灵活多样的内容集合,它能以网格、流水等多种形式呈现数据元素,像展示图片集、商品列表等场景都很适用。开发者可借助相关布局类(如UICollectionViewFlowLayout
等)以及遵循对应代理协议,来定制单元格外观、尺寸、间距等布局细节,从而打造出符合不同需求的美观且实用的界面效果。
实现九宫格布局
这里实现一个九宫格布局来简单的使用一下UICollectionView,实现的步骤很简单:
- 创建布局类为其各个属性赋值。
- 将其传递给UICollectionView的初始化方法:
\- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout NS_DESIGNATED_INITIALIZER;
- 设置代理,实现相关方法。
实现代码:
@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor whiteColor];UICollectionViewFlowLayout* layout = [[UICollectionViewFlowLayout alloc] init];//设置一个垂直流布局layout.scrollDirection = UICollectionViewScrollDirectionVertical;//设置每个item的大小是100*100layout.itemSize = CGSizeMake(100, 100);layout.minimumInteritemSpacing = 10;_collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];_collectionView.delegate = self;_collectionView.dataSource = self;[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellid"];[self.view addSubview: _collectionView];}- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 1;
}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return 101;
}- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {UICollectionViewCell* cell = [_collectionView dequeueReusableCellWithReuseIdentifier:@"cellid" forIndexPath:indexPath];cell.backgroundColor = [UIColor colorWithRed: arc4random() % 255 / 255.0 green: arc4random() % 255 / 255.0 blue: arc4random() % 255 / 255.0 alpha: 1.0];return cell;
}
@end
layout中常用的一些属性
itemSize
:设置item的大小。
minimumLineSpacing
:设置item每一行之间的间距。
minimumInteritemSpacing
:设置每行中item之间的间距。这里需要注意的是,系统通过minimumInteritemSpacing
属性计算一行可以放多少个item,当发现放不下计算好的item个数时,为了撑满所在行,此值就会变大
scrollDirection
:设置滚动的方向。
UICollectionView有两种布局方法分别为水平流和垂直流,简单来说就是,一个是竖屏滚动,一个是横屏滚动,在笔者的学习过程中笔者均使用的是垂直流布局。
sectionInset
:设置分区之间的间距。
在设置item大小的时候,我们可以使用协议中的方法让item的大小不同:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {if (indexPath.item % 2) {return CGSizeMake((self.view.bounds.size.width - 12) / 3, (self.view.bounds.size.width - 12) / 3);} else {return CGSizeMake((self.view.bounds.size.width - 12) / 6, (self.view.bounds.size.width - 12) / 6);}
}
效果图:
参差瀑布流的实现
我们要实现一个参差效果的瀑布流时就需要我们使用UICollectionViewFlowLayout
的自定义子类来实现,由于item的高度不一,故而原来OC提供的无法实现这个效果。
声明自定义子类
Mylayout.h:
#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface Mylayout : UICollectionViewFlowLayout
@property (nonatomic, copy) NSMutableArray* attributaArray;
@property (nonatomic, copy) NSMutableArray* columnHeight;
@property (nonatomic, assign) NSInteger itemCount;
@endNS_ASSUME_NONNULL_END
Mylaout.m:
#import "Mylayout.h"@implementation Mylayout- (void)prepareLayout {_attributaArray = [NSMutableArray array];[super prepareLayout];CGFloat cellWidth = ([UIScreen mainScreen].bounds.size.width - self.sectionInset.right - self.sectionInset.left - self.minimumInteritemSpacing) / 2;_columnHeight = [NSMutableArray arrayWithObjects:@(self.sectionInset.top), @(self.sectionInset.top), nil];for(int i = 0; i < _itemCount; i++) {NSIndexPath* index = [NSIndexPath indexPathForRow:i inSection:0];UICollectionViewLayoutAttributes* attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:index];CGFloat height = arc4random() % 200 + 50;NSInteger minLine = [_columnHeight[0] doubleValue] < [_columnHeight[1] doubleValue] ? 0 : 1;_columnHeight[minLine] = @([_columnHeight[minLine] doubleValue] + self.minimumLineSpacing + height);attribute.frame = CGRectMake(self.sectionInset.left + (self.minimumInteritemSpacing + cellWidth) * minLine,[_columnHeight[minLine] doubleValue] - height - self.minimumLineSpacing,cellWidth, height);[_attributaArray addObject:attribute];}
}- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {return _attributaArray;
}- (CGSize)collectionViewContentSize {CGFloat fristHeight = [_columnHeight[0] doubleValue];CGFloat secondHeight = [_columnHeight[1] doubleValue];CGFloat maxHeight = fristHeight > secondHeight ? fristHeight : secondHeight;return CGSizeMake(0, maxHeight);
}@end
这里我们在设置自定义子类的时候,我们必须要实现以下几个方法:
- (void)prepareLayout;//提前进行布局
- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;//返回所有元素的布局属性,一般情况下返回的是一个数组
- (CGSize)collectionViewContentSize;//设置画布大小