效果图
一.我们要对UICollectionView的布局进行自定义
这是我自定义的宏以及静态变量
#define WIDTH [UIScreen mainScreen].bounds.size.width
#define Height [UIScreen mainScreen].bounds.size.height
#define CWColor(a,b,c) [UIColor colorWithRed:(a)/255.0 green:(b)/255.0 blue:(c)/255.0 alpha:1.0]
/**
* static 表示只在此文件里可以访问(防止其他文件访问) const防止别人去改
*/
static NSString *const ID = @"cellID";
-
1.自定义布局,集成
UICollectionViewFlowLayout
即可布局的设置(重点)
UICollectionViewFlowLayout
继承它就拥有流水的效果
UICollectionViewLayout
如果继承它,那么一切布局要从头开始
下面我们就重点讲讲自定义布局的里面一些知识点,我就以我布局的CWLineLayout为例#import "CwLineLayout.h" #define WIDTH [UIScreen mainScreen].bounds.size.width #define Height [UIScreen mainScreen].bounds.size.height static const CGFloat CWItemH = 120; @implementation CwLineLayout -(instancetype)init { self = [super init]; if (self) { } return self; } /** * 此方法可在collectionView之后进行走的 */ -(void)prepareLayout { //设置格子的大小 self.itemSize = CGSizeMake(CWItemH, CWItemH); CGFloat inset = (self.collectionView.frame.size.width-CWItemH)*0.5; self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset); self.minimumLineSpacing = 100; /** * 设置滑动方向 * UICollectionViewScrollDirectionHorizontal 水平方向 * UICollectionViewScrollDirectionVertical 垂直方向 */ self.scrollDirection = UICollectionViewScrollDirectionHorizontal; /* // //设置最小行间距 // self.minimumLineSpacing = 10; // // //设置最小列间距 // self.minimumInteritemSpacing = 10; // // //设置与四周的边距 // self.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5); */ /** * 每一个cell(item)都有自己的UICollectionViewLayoutAttributes * 每一个indexPath都有自己的UICollectionViewLayoutAttributes */ } /** * 用来设置collectionView停止滚动那一刻的位置 * * @param proposedContentOffset collectionView原本停留的位置 * @param velocity 滚动的速度 */ -(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { //1.计算scrollview最后会停留的范围 CGRect lastRect; lastRect.origin = proposedContentOffset; lastRect.size = self.collectionView.frame.size; //计算屏幕最中间的x CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width*0.5; //2.取出这个范围内的所有属性 NSArray *array1 = [self layoutAttributesForElementsInRect:lastRect]; //遍历所有的属性 CGFloat adjustOffsetX = MAXFLOAT; for (UICollectionViewLayoutAttributes *array2 in array1) { if (ABS(array2.center.x - centerX) < ABS(adjustOffsetX)) { adjustOffsetX = array2.center.x - centerX; } } return CGPointMake(proposedContentOffset.x+adjustOffsetX, proposedContentOffset.y); } /** * 对collection的滚动进行实时监控 * 只要显示的便捷发生改变就进行重新布局,内部会重新调用 layoutAttributesForElementsInRect:(CGRect)rect,获得所有cell的布局属性 */ -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } /** * 对传进来的item进行监听 */ -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect { //计算呢可见的矩形框 CGRect visiableRect; visiableRect.size = self.collectionView.frame.size; visiableRect.origin = self.collectionView.contentOffset; //1.取出默认的cell的 UICollectionViewLayoutAttributes,super是返回所有的图片 NSArray *array = [super layoutAttributesForElementsInRect:rect]; //计算屏幕最中间的x CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width*0.5; //2.遍历所有的布局属性 for (UICollectionViewLayoutAttributes *attributes in array) { if (!CGRectIntersectsRect(visiableRect, attributes.frame)) { continue; } //每一个item中点的x CGFloat itemCenterX = attributes.center.x; //根据屏幕最中间的距离计算缩放比例,差距越小缩放比例越大 CGFloat scale = 1+ 1 - ABS(itemCenterX - centerX)/(self.collectionView.frame.size.width*0.5); attributes.transform3D = CATransform3DMakeScale(scale, scale, scale); } return array; } @end
- 2.建立
UICollectionView
(挂代理,遵守协议)
<UICollectionViewDataSource,UICollectionViewDelegate>
- 2.建立
/**
* UICollectionView的创建
*/
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 100, WIDTH, WIDTH) collectionViewLayout:layout];
collectionView.backgroundColor = CWColor(255, 255, 0);
collectionView.showsHorizontalScrollIndicator = NO;
collectionView.delegate = self;
collectionView.dataSource = self;
/**
* 注册UICollectionView
*/
[collectionView registerNib:[UINib nibWithNibName:@"CWImageCell" bundle:nil] forCellWithReuseIdentifier:ID];
[self.view addSubview: collectionView];
3.CollectionView的代理方法
#pragma mark collectionView的代理方法的实现
-(NSInteger )collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.imageArray.count;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CWImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
cell.imageName = self.imageArray[indexPath.item];
cell.number.text = [NSString stringWithFormat:@"%ld",(long)indexPath.item+1];
return cell;
}
/**
* collectionView的点击事件
*/
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//删除模型数据(删除的指定item)
[self.imageArray removeObjectAtIndex:indexPath.item];
//刷新UI
[collectionView deleteItemsAtIndexPaths:@[indexPath]];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
/**
* 动画式切换
*/
if ([self.collectionView.collectionViewLayout isKindOfClass:[CwLineLayout class]]) {
[self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc]init] animated:YES];
}else
{
[self.collectionView setCollectionViewLayout:[[CwLineLayout alloc]init] animated:YES];
}
}
#pragma mark 图片数组化
-(NSMutableArray *)imageArray
{
if (!_imageArray) {
_imageArray = [[NSMutableArray alloc]init];
for (int i = 1; i <= 13 ; i++) {
[_imageArray addObject:[NSString stringWithFormat:@"%d.jpg",i]];
}
}
return _imageArray;
}
简单的相册demo 密码: fm69
实例2旋转相册 密码:hwh3
值得注意的是layout的一个属性
// zIndex越大,就越在上面
attrs.zIndex = [self.collectionView numberOfItemsInSection:indexPath.section] - indexPath.item;
实例3.圆形角度相册 密码: yj7w
大总结:在进行layout 进行布局时记住如下几点:
-
1.继承方式
UICollectionViewFlowLayout 继承它就拥有流水的效果
UICollectionViewLayout 如果继承它,那么一切布局要从头开始
-
2.在第二种继承方式里面layout重新布局的类.m中不可缺少的方法(一般来说这3个方法不可缺少)
/** * 对collection的滚动进行实时监控 * 只要显示的便捷发生改变就进行重新布局,内部会重新调用 layoutAttributesForElementsInRect:(CGRect)rect,获得所有cell的布局属性 */ -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } /** * 位置改变就重新布局 */ -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *array = [NSMutableArray array]; NSInteger count = [self.collectionView numberOfItemsInSection:0]; for (int i = 0; i < count; i++) { UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]]; [array addObject:attrs]; } return array; } //在此里面进行自己想要的设置 -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; attrs.size = CGSizeMake(50,50); attrs.zIndex = indexPath.item; return attrs; }
提示: UICollectionView 滚动条去掉
垂直滚动条
XXX.showsVerticalScrollIndicator = NO;
水平滚动条
XXX.showsHorizontalScrollIndicator = NO;