效果圖

Untitled11卡片動畫1.gif
一.我們要對UICollectionView的布局進(jìn)行自定義
這是我自定義的宏以及靜態(tài)變量
#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即可布局的設(shè)置(重點(diǎn))
UICollectionViewFlowLayout繼承它就擁有流水的效果
UICollectionViewLayout如果繼承它,那么一切布局要從頭開始
下面我們就重點(diǎn)講講自定義布局的里面一些知識點(diǎn),我就以我布局的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之后進(jìn)行走的 */ -(void)prepareLayout { //設(shè)置格子的大小 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; /** * 設(shè)置滑動方向 * UICollectionViewScrollDirectionHorizontal 水平方向 * UICollectionViewScrollDirectionVertical 垂直方向 */ self.scrollDirection = UICollectionViewScrollDirectionHorizontal; /* // //設(shè)置最小行間距 // self.minimumLineSpacing = 10; // // //設(shè)置最小列間距 // self.minimumInteritemSpacing = 10; // // //設(shè)置與四周的邊距 // self.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5); */ /** * 每一個cell(item)都有自己的UICollectionViewLayoutAttributes * 每一個indexPath都有自己的UICollectionViewLayoutAttributes */ } /** * 用來設(shè)置collectionView停止?jié)L動那一刻的位置 * * @param proposedContentOffset collectionView原本停留的位置 * @param velocity 滾動的速度 */ -(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { //1.計(jì)算scrollview最后會停留的范圍 CGRect lastRect; lastRect.origin = proposedContentOffset; lastRect.size = self.collectionView.frame.size; //計(jì)算屏幕最中間的x CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width*0.5; //2.取出這個范圍內(nèi)的所有屬性 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的滾動進(jìn)行實(shí)時監(jiān)控 * 只要顯示的便捷發(fā)生改變就進(jìn)行重新布局,內(nèi)部會重新調(diào)用 layoutAttributesForElementsInRect:(CGRect)rect,獲得所有cell的布局屬性 */ -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } /** * 對傳進(jìn)來的item進(jìn)行監(jiān)聽 */ -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect { //計(jì)算呢可見的矩形框 CGRect visiableRect; visiableRect.size = self.collectionView.frame.size; visiableRect.origin = self.collectionView.contentOffset; //1.取出默認(rèn)的cell的 UICollectionViewLayoutAttributes,super是返回所有的圖片 NSArray *array = [super layoutAttributesForElementsInRect:rect]; //計(jì)算屏幕最中間的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中點(diǎn)的x CGFloat itemCenterX = attributes.center.x; //根據(jù)屏幕最中間的距離計(jì)算縮放比例,差距越小縮放比例越大 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(掛代理,遵守協(xié)議)
<UICollectionViewDataSource,UICollectionViewDelegate>
- 2.建立
/**
* UICollectionView的創(chuàng)建
*/
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的代理方法的實(shí)現(xiàn)
-(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的點(diǎn)擊事件
*/
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//刪除模型數(shù)據(jù)(刪除的指定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 圖片數(shù)組化
-(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
實(shí)例2旋轉(zhuǎn)相冊 密碼:hwh3

旋轉(zhuǎn)相冊
值得注意的是layout的一個屬性
// zIndex越大,就越在上面
attrs.zIndex = [self.collectionView numberOfItemsInSection:indexPath.section] - indexPath.item;
實(shí)例3.圓形角度相冊 密碼: yj7w

圓形角度相冊.gif
大總結(jié):在進(jìn)行l(wèi)ayout 進(jìn)行布局時記住如下幾點(diǎn):
-
1.繼承方式
UICollectionViewFlowLayout 繼承它就擁有流水的效果
UICollectionViewLayout 如果繼承它,那么一切布局要從頭開始
-
2.在第二種繼承方式里面layout重新布局的類.m中不可缺少的方法(一般來說這3個方法不可缺少)
/** * 對collection的滾動進(jìn)行實(shí)時監(jiān)控 * 只要顯示的便捷發(fā)生改變就進(jìn)行重新布局,內(nèi)部會重新調(diào)用 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; } //在此里面進(jìn)行自己想要的設(shè)置 -(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;