//
// 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.width
static NSString * const ID = @"cell";
@interface ViewController ()<UICollectionViewDataSource>
@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://pan.baidu.com/s/1eQOOixc 密码: duu8
源码:
// PhotoCell.h
// 自定义流水布局
//
// Created by xmg on 16/1/15.
// Copyright © 2016年 HeYang. All rights reserved.
//
#import <UIKit/UIKit.h>
@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 <UIKit/UIKit.h> @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.width
static NSString * const ID = @"cell";
@interface ViewController ()<UICollectionViewDataSource>
@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