本文共 7180 字,大约阅读时间需要 23 分钟。
//// ViewController.m// 自定义流水布局//// Created by xmg on 16/1/15.// Copyright © 2016年 HeYang. All rights reserved.//#import "ViewController.h"#import "PhotoCell.h"#import "PhotoLayout.h"/* // a , b , c a = b + c // int d = (2,3,5); // 高聚合,低耦合 int a = ({ int b = 2; int c = 3; a = b + c; 20; }); *//* UICollectionView注意点: 1.初始化必须要传入布局,(流水布局:九宫格布局) 2.UICollectionViewCell必须要注册 3.必须自定义cell */#define XMGScreenW [UIScreen mainScreen].bounds.size.widthstatic NSString * const ID = @"cell";@interface ViewController ()@end@implementation ViewController// 思路:照片浏览布局:流水布局,在拖到的时候,在原来基础上重新计算下布局 -> 在原来功能上再添加功能,自定义流水布局- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 创建流水布局 PhotoLayout *layout = ({ layout = [[PhotoLayout alloc] init]; // 尺寸 layout.itemSize = CGSizeMake(180, 180); // 设置滚动方向:水平 layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; // 设置额外滚动区域 CGFloat inset = (XMGScreenW - 180) * 0.5; layout.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset); layout; }); // 创建UICollectionView:默认为黑色 UICollectionView *collectionView = ({ collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; collectionView.bounds = CGRectMake(0, 0, self.view.bounds.size.width, 200); collectionView.center = self.view.center; collectionView.backgroundColor = [UIColor cyanColor]; collectionView.showsHorizontalScrollIndicator = NO; [self.view addSubview:collectionView]; // 设置数据源 collectionView.dataSource = self; collectionView; }); // 注册cell [collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([PhotoCell class]) bundle:nil] forCellWithReuseIdentifier:ID];}#pragma mark -UICollectionViewDataSource// 返回有多少个cell- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return 20;}// 返回每个cell长什么样- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath]; NSString *imageName = [NSString stringWithFormat:@"%ld",indexPath.row + 1]; cell.image = [UIImage imageNamed:imageName]; return cell;}@end
前言:因为时间缘故,很少进行通俗易懂的算法思路讲解,这里先展示动态图片效果,然后后面的内容我就直接上关键源码了。
效果展示图;
源码百度云盘下载链接: 密码: duu8
源码:
// PhotoCell.h// 自定义流水布局//// Created by xmg on 16/1/15.// Copyright © 2016年 HeYang. All rights reserved.//#import@interface PhotoCell : UICollectionViewCell@property (nonatomic, strong) UIImage *image;@end================两个文件的分水岭==================//// PhotoCell.m// 自定义流水布局//// Created by xmg on 16/1/15.// Copyright © 2016年 HeYang. All rights reserved.//26 #import "PhotoCell.h"@interface PhotoCell ()@property (weak, nonatomic) IBOutlet UIImageView *imageView;@end@implementation PhotoCell- (void)awakeFromNib { // Initialization code}- (void)setImage:(UIImage *)image{ _image = image; _imageView.image = image; }@end
//// PhotoLayout.h// 自定义流水布局//// Created by xmg on 16/1/15.// Copyright © 2016年 HeYang. All rights reserved.//#import@interface PhotoLayout : UICollectionViewFlowLayout@end==============两个文件的分水岭================//// PhotoLayout.m// 自定义流水布局//// Created by xmg on 16/1/15.// Copyright © 2016年 HeYang. All rights reserved.//#import "PhotoLayout.h"#define XMGScreenW [UIScreen mainScreen].bounds.size.width@implementation PhotoLayout// 复杂效果: 分析 ->// cell离中心点距离越近(delta越小),就越大,越远,就越小// 距离中心点// 知道哪些cell需要缩放:显示出来的cell才需要进行布局// 给定一个区域,就返回这个区域内所有cell布局- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{ // 1.获取显示区域,bounds 而不是整个滚动区域,这样设置的子控件就控制在显示区域范围内了。 CGRect visiableRect = self.collectionView.bounds; // 2.获取显示区域内的cell的布局 NSArray *attributes = [super layoutAttributesForElementsInRect:visiableRect]; // 3.遍历cell布局 CGFloat offsetX = self.collectionView.contentOffset.x; for (UICollectionViewLayoutAttributes *attr in attributes) { // 3.1 计算下距离中心点距离 CGFloat delta = fabs(attr.center.x - offsetX - XMGScreenW * 0.5); // 1 ~ 0.75 CGFloat scale = 1 - delta / (XMGScreenW * 0.5) * 0.25;//1-(0~0.5) = 1~0.5 --> 1-(0~0.5)×0.25 = (1~0.75) attr.transform = CGAffineTransformMakeScale(scale, scale); } return attributes;}// Invalidate:刷新// 是否允许在拖动的时候刷新布局// 谨慎使用,YES:只要一滚动就会布局- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{ return YES;}
最后的关键代码:
//// ViewController.m// 自定义流水布局//// Created by xmg on 16/1/15.// Copyright © 2016年 HeYang. All rights reserved.//#import "ViewController.h"#import "PhotoCell.h"#import "PhotoLayout.h"/* // a , b , c a = b + c // int d = (2,3,5); // 高聚合,低耦合 int a = ({ int b = 2; int c = 3; a = b + c; 20; }); *//* UICollectionView注意点: 1.初始化必须要传入布局,(流水布局:九宫格布局) 2.UICollectionViewCell必须要注册 3.必须自定义cell */#define XMGScreenW [UIScreen mainScreen].bounds.size.widthstatic NSString * const ID = @"cell";@interface ViewController ()@end@implementation ViewController// 思路:照片浏览布局:流水布局,在拖到的时候,在原来基础上重新计算下布局 -> 在原来功能上再添加功能,自定义流水布局- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 创建流水布局 PhotoLayout *layout = ({ layout = [[PhotoLayout alloc] init]; // 尺寸 layout.itemSize = CGSizeMake(180, 180); // 设置滚动方向:水平 layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; // 设置额外滚动区域 CGFloat inset = (XMGScreenW - 180) * 0.5; layout.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset); layout; }); // 创建UICollectionView:默认为黑色 UICollectionView *collectionView = ({ collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; collectionView.bounds = CGRectMake(0, 0, self.view.bounds.size.width, 200); collectionView.center = self.view.center; collectionView.backgroundColor = [UIColor cyanColor]; collectionView.showsHorizontalScrollIndicator = NO; [self.view addSubview:collectionView]; // 设置数据源 collectionView.dataSource = self; collectionView; }); // 注册cell [collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([PhotoCell class]) bundle:nil] forCellWithReuseIdentifier:ID];}#pragma mark -UICollectionViewDataSource// 返回有多少个cell- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return 20;}// 返回每个cell长什么样- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath]; NSString *imageName = [NSString stringWithFormat:@"%ld",indexPath.row + 1]; cell.image = [UIImage imageNamed:imageName]; return cell;}@end
转载地址:http://pbcda.baihongyu.com/