iOS:UICollectionView纯自定义的布局:堆叠式布局、圆式布局 (一般用来制作相册)
集合视图的自动布局:UICollectionViewLayout是抽象根类,必须用它的子类才能创建实例,下面是重写的方法,计算item的布局属性
//每一次重新布局前,都会准备布局(苹果官方推荐使用该方法进行一些初始化)
-(void)prepareLayout
//重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性(流式布局内部已经帮助完成)
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
//是否要重新刷新布局(只要显示的item边界发生改变就重新布局)
//只要每一次重新布局内部就会调用下面的layoutAttributesForElementsInRect:获取所有cell(item)的属性
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
//返回需要重新布局的所有item的属性
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
🐷下面的这两个布局可以直接带走使用,不需要做任何其他的操作,欧耶
堆叠式布局代码如下:
CustomStackLayout.h
#import <UIKit/UIKit.h> @interface CustomStackLayout : UICollectionViewLayout @end
CustomStackLayout.m
#import "CustomStackLayout.h" #define RANDOM_0_1 arc4random_uniform(100)/100.0 /* 由于CustomStackLayout是直接继承自UICollectionViewLayout的,父类没有帮它完成任何的布局,因此, 需要用户自己完全重新对每一个item进行布局,也即设置它们的布局属性UICollectionViewLayoutAttributes */ @implementation CustomStackLayout //重写shouldInvalidateLayoutForBoundsChange,每次重写布局内部都会自动调用 -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } //重写collectionViewContentSize,可以让collectionView滚动 -(CGSize)collectionViewContentSize { return CGSizeMake(400, 400); } //重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性 -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { //创建布局实例 UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; //设置布局属性 attrs.size = CGSizeMake(100, 100); attrs.center = CGPointMake(self.collectionView.frame.size.width*0.5, self.collectionView.frame.size.height*0.5); //设置旋转方向 //int direction = (i % 2 ==0)? 1: -1; NSArray *directions = @[@0.0,@1.0,@(0.05),@(-1.0),@(-0.05)]; //只显示5张 if (indexPath.item >= 5) { attrs.hidden = YES; } else { //开始旋转 attrs.transform = CGAffineTransformMakeRotation([directions[indexPath.item]floatValue]); //zIndex值越大,图片越在上面 attrs.zIndex = [self.collectionView numberOfItemsInSection:indexPath.section] - indexPath.item; } return attrs; } //重写layoutAttributesForElementsInRect,设置所有cell的布局属性(包括item、header、footer) -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *arrayM = [NSMutableArray array]; NSInteger count = [self.collectionView numberOfItemsInSection:0]; //给每一个item创建并设置布局属性 for (int i = 0; i < count; i++) { //创建item的布局属性 UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]]; [arrayM addObject:attrs]; } return arrayM; } @end
圆式布局代码如下:
CustomCircleLayout.h
#import <UIKit/UIKit.h> @interface CustomCircleLayout : UICollectionViewLayout @end
CustomCirclelayout.m
#import "CustomCircleLayout.h" @implementation CustomCircleLayout //重写shouldInvalidateLayoutForBoundsChange,每次重写布局内部都会自动调用 -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } //重写layoutAttributesForItemAtIndexPath,返回每一个item的布局属性 -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { //创建布局实例 UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; //设置item的大小 attrs.size = CGSizeMake(50, 50); //设置圆的半径 CGFloat circleRadius = 70; //设置圆的中心点 CGPoint circleCenter = CGPointMake(self.collectionView.frame.size.width*0.5, self.collectionView.frame.size.height *0.5); //计算每一个item之间的角度 CGFloat angleDelta = M_PI *2 /[self.collectionView numberOfItemsInSection:indexPath.section]; //计算当前item的角度 CGFloat angle = indexPath.item * angleDelta; //计算当前item的中心 CGFloat x = circleCenter.x + cos(angle)*circleRadius; CGFloat y = circleCenter.y - sin(angle)*circleRadius; //定位当前item的位置 attrs.center = CGPointMake(x, y); //设置item的顺序,越后面的显示在前面 attrs.zIndex = indexPath.item; return attrs; } //重写layoutAttributesForElementsInRect,设置所有cell的布局属性(包括item、header、footer) -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *arrayM = [NSMutableArray array]; NSInteger count = [self.collectionView numberOfItemsInSection:0]; //给每一个item创建并设置布局属性 for (int i = 0; i < count; i++) { //创建item的布局属性 UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]]; [arrayM addObject:attrs]; } return arrayM; } @end
堆叠式布局演示: 圆式布局演示:
github: https://github.com/xiayuanquan/XYQCollectionLayout.git
程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!