一 整体功能图和实现思路

1 完整的功能图:

2 实现功思路:

1> 流水布局(实现UICollectionView必需要的条件)
2> 自己定义cell(实现UICollectionView必需要的条件)
3> 自己定义流水布局
4> 假设想冲缓存池中取,那么必须採用注冊的方法
5> 照片缩放
6> 照片移动后自己主动定位功能
7> 一种新的封装思路

二 流水布局

1 包含下面部分:

—> 1> cell的大小
—> 2> 滚动方向
—> 3> 实现照片墙的额外滚动区域
—> 4> 每一个cell之间的距离

2 下面是未封装的代码:

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
//最小水平距离
layout.minimumInteritemSpacing = XFJ_space;
//每一个cell的大小
layout.itemSize = CGSizeMake(XFJ_sizeXY, XFJ_sizeXY);
//设置额外的滚动数
CGFloat margin = (XFJ_screenW - XFJ_sizeXY) * 0.5;
////左边和右边空出来的额外滚动区域
layout.sectionInset = UIEdgeInsetsMake(XFJ_zero, margin, XFJ_zero, margin);
//设置滚动方向(水平)
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

三 UICollectionView对象创建与相关设置

1 包含下面部分:

—> 1> UICollectionView对象的尺寸,位置
—> 2> 背景颜色
—> 3> 设置代理

2 下面是未封装的代码:

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
//bounds
collectionView.bounds = CGRectMake(XFJ_zero, XFJ_zero, self.view.bounds.size.width, 200);
//center
collectionView.center = self.view.center;
//隐藏底部的滚动栏
collectionView.showsHorizontalScrollIndicator = NO;
//设置背景颜色
collectionView.backgroundColor = [UIColor brownColor];
//加入到控制器的view中
[self.view addSubview:collectionView];
//设置代理
collectionView.dataSource = self;

四 数据源方法

1 包含下面部分:

—> 1> 总共几组
—> 2> cell的个数
—> 3> cell中的内容

2 代码部分:

#pragma mark - 数据源方法(组数,不写默认为一组)
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
} #pragma mark - cell的个数 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 20;
} #pragma mark - 每一个cell的内容
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
//去缓存池中找
XFJFlowCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath]; NSString *imageName = [NSString stringWithFormat:@"%zd",indexPath.row + 1]; cell.image = [UIImage imageNamed:imageName]; return cell;
}

五 自己定义cell

1 自己定义的时候同一时候创建一个xib

2 定义一个图片属性

@property (nonatomic, strong) UIImage *image;

3 通过从xib中拖线的方式,拿到UIImageView对象,用来设置图片

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

4 重写定义好的属性的set方法

- (void)setImage:(UIImage *)image
{
_image = image; self.imageView.image = image;
}

5 将设置cell内容中的cell类型改为自己定义的类型,让程序载入的时候,直接载入自己定义的类型

六 注冊

1 注意: 运用UICollectionView的时候,假设想从缓存池中取,那么必需要採用注冊的方法,採用一般的方法是不能够的.

2 代码部分:

//注冊
[collectionView registerNib:[UINib nibWithNibName:@"XFJFlowCell" bundle:nil] forCellWithReuseIdentifier:ID];

七 自己定义流水布局

1 自己定义原因: 假设想要达到整个app执行的效果图,那么传统的流水布局是无法实现的,那么我们就需要自己定义.以后再开发中也是这样,在开发中大多数的功能,系统是无法实现的,那么我们就需要自己定义.

2 创建自己定义流水布局(继承系统的类)

3 照片的缩放

3.1 必需要知道的事: 我们通过观察效果图知道,并非全部的cell都需要缩放,仅仅是在我们视线范围内的图片需要缩放.
3.2 怎样计算缩放比例?

3.3 依据什么来进行缩放的?

代码部分:

//给定个区域,返回这个区域内全部cell的布局
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
//获取显示的cell的布局
NSArray *atts = [super layoutAttributesForElementsInRect:self.collectionView.bounds];
//获取collectionView的宽度
CGFloat width = self.collectionView.bounds.size.width;
//获取collectionView的偏移量
CGFloat offsetX = self.collectionView.contentOffset.x;
//遍历全部的cell
for (UICollectionViewLayoutAttributes *att in atts) { //计算离中心点的距离
CGFloat delta = fabs(att.center.x - (width * 0.5 + offsetX));
//缩放比例
CGFloat scal = 1 - delta / (width * 0.5) * 0.25;
att.transform = CGAffineTransformMakeScale(scal, scal);
}
return atts;
}

4 照片定位功能

4.1 当我们用手指拖动照片,然后停止的时候,照片会定位到中心点的位置
4.2 实现思路: 计算出中心点,然后通过与中心点的距离做比較,离中心点近的图片,就自己主动定位到中心位置
4.3 明白: 假设用户高速拖动,而且停止的时候,照片会有缓冲,要知道怎样计算偏移量.

详细的代码:

//手指离开,拖动完毕的时候调用
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
//获取collectionView的宽度
CGFloat width = self.collectionView.bounds.size.width;
//获取终于显示区域
CGRect targetR = CGRectMake(proposedContentOffset.x, 0, width, MAXFLOAT);
//获取终于显示的cell
NSArray *atts = [super layoutAttributesForElementsInRect:targetR];
//获取cell离中心点的距离
//定义一个变量记录最小的中心距离
CGFloat minDelta = MAXFLOAT;
for (UICollectionViewLayoutAttributes *att in atts) {
//获取中心距离
CGFloat delta = att.center.x - (width * 0.5 + proposedContentOffset.x);
//推断
if (fabs(delta) < fabs(minDelta)) {
minDelta = delta;
} }
//终于的偏移量加上离中心点的距离
proposedContentOffset.x += minDelta;
//推断,假设终于的偏移量小于0
if (proposedContentOffset.x < 0) {
proposedContentOffset.x = 0;
} return proposedContentOffset;
}

5 将系统的流水布局,改为自己定义的流水布局.

八 前提

注意: 在实现上面对比片的缩放,和自己主动定位功能的方法的前提下,我们必需要实现下面的代码,假设不实现,是无法达到效果的.会出现故障.

1 仅仅要滚动就会刷新

//滚动的时候是否刷新布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}

九 新的封装方法

1 思路:运用到了C语言中的思路,下面的代码中值等于最后一个.

int a = ({
int b = 2;
int c = 3;
int d = 4;
a = b + c + d;
5;
});

2 详细对流水布局和创建UICollectionView对象的封装代码:

2.1 封装代码块一:

//封装一:
//流水布局
XFJFlowLayout *layout = ({
XFJFlowLayout *layout = [[XFJFlowLayout alloc] init];
//最小水平距离
layout.minimumInteritemSpacing = XFJ_space;
//每一个cell的大小
layout.itemSize = CGSizeMake(XFJ_sizeXY, XFJ_sizeXY);
//设置额外的滚动数
CGFloat margin = (XFJ_screenW - XFJ_sizeXY) * 0.5;
////左边和右边空出来的额外滚动区域
layout.sectionInset = UIEdgeInsetsMake(XFJ_zero, margin, XFJ_zero, margin);
//设置滚动方向(水平)
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
//取的是最后的值
layout;
});

2.2 封装代码块二:

//封装二:
//创建UICollectionView
UICollectionView *collectionView = ({
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
//bounds
collectionView.bounds = CGRectMake(XFJ_zero, XFJ_zero, self.view.bounds.size.width, 200);
//center
collectionView.center = self.view.center;
//隐藏底部的滚动栏
collectionView.showsHorizontalScrollIndicator = NO;
//设置背景颜色
collectionView.backgroundColor = [UIColor brownColor];
//加入到控制器的view中
[self.view addSubview:collectionView];
//设置代理
collectionView.dataSource = self;
//取的是最后的值
collectionView;
});

3 封装的优点

1> 能非常快的找到相应的位置.比方:假设是流水布局需要改动,就能直接找到流水布局的代码块;同理也非常快的找到UICollectionView中的代码块进行改动
2> 给阅读代码的人眼前一种新奇的感觉,感觉非常高大上.同一时候也可能会影响一部分人对代码不easy读懂(C语言知识比較薄弱).

十 总结

1 该文简单的对UICollectionView的使用方法进行了补充,里面涉及到了比較多的数学运算,调理还算是比較清晰

2 该文给大家提供了一种新的封装思想

3 希望能帮到大家,提高大家,大家有什么意见,麻烦请留言,假设你认为还惬意的话,请关注我的官方博客,谢谢!!!!

UICollectionView使用方法补充(照片轮播墙)的更多相关文章

  1. vue中引入awesomeswiper的方法以及编写轮播组件

    1.先安装less-loader npm install less less-loader --save 2.再安装css-loader npm install css-loader --save 3 ...

  2. 原生Js_使用setInterval() 方法实现图片轮播功能

    用javascript图片轮播功能 <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  3. 关于最近在做的一个js全屏轮播插件

    最近去面试了,对方要求我在一个星期内用原生的js代码写一个全屏轮播的插件,第一想法就是跟照片轮播很相似,只是照片轮播是有定义一个宽高度大小已经确定了的容器用来存储所有照片,然后将照片全部左浮动,利用m ...

  4. android中广告轮播图总结

    功能点:无限轮播.指示点跟随.点击响应.实现思路: 1.指示点跟随,指示点通过代码动态添加,数量由图片数量决定. 在viewpager的页面改变监听中,设置点的状态选择器enable,当前页时,set ...

  5. Bootstrap插件之Carousel轮播效果(2015年-05月-21日)

    <!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"& ...

  6. 李洪强iOS开发之使用CycleScrollView实现轮播图

    01 导入头文件,并且定义CycleScrollView属性 02 初始化,设置frame并且添加到collectionView上 03 调用方法并且设置轮播的图片

  7. JQ万能轮播图

    lunbotu.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8">  ...

  8. Android项目实战(四十七):轮播图效果Viewpager

    简易.常用的轮播图效果ViewPager ,老技术了,记一笔留着以后ctrl C + ctrl V    需求如下: 不定张个数的ImagView轮播,右下角显示轮播点图标,每隔固定时间切换下一张,最 ...

  9. [android] 轮播图-滑动图片标题焦点

    谷歌提供的v4包,ViewPager 在布局文件中,先添加<android.support.v4.view.ViewPager/>控件,这个只是轮播的区域 在布局文件中,布置标题描述部分 ...

随机推荐

  1. 【Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) D】Bash and a Tough Math Puzzle

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 对于1操作 令len = r-l+1 等价于查找l..r这个范围内x的倍数的个数是否大于等于len-1 也即l..r这个范围内不是x ...

  2. 【习题 8-2 UVA-1610】Party Games

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 字符串排序后 显然是n/2-1和n/2这两个字符串进行比较. 设为a,b 找到第一个不相同的位置. 即0..i-1是相同的前缀,然后 ...

  3. CODEVS——T 3013 单词背诵

    http://codevs.cn/problem/3013/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 De ...

  4. 摆脱技术思维,转向产品思维——寻找“万能”IDC的苦恼

    背景:近期在新产品的开发任务完毕后一直在为寻找好的IDC和优质的托管服务忙碌.需求源自于我们重点要解决之前老版产品面临的国内外用户訪问速度慢甚至连接不上的问题. 除去架构技术上使用高性能.可扩展的方案 ...

  5. HDU1023 Train Problem II【Catalan数】

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1023 题目大意: 一列N节的火车以严格的顺序到一个站里.问出来的时候有多少种顺序. 解题思路: 典型 ...

  6. 正确理解Widget::Widget(QWidget *parent) :QWidget(parent)这句话(初始化列表中无法直接初始化基类的数据成员,所以你需要在列表中指定基类的构造函数)

    最近有点忙,先发一篇我公众号的文章,以下是原文. /********原文********/ 最近很多学习Qt的小伙伴在我的微信公众号私信我,该如何理解下面段代码的第二行QWidget(parent) ...

  7. Monkey测试执行指导

    1.Monkey常规测试

  8. idea添加自动编译

    话不多说,idea每次修改文件不自动编译到项目里,这里做一下一些操作 registry快捷键ctrl+shift+alt+/

  9. selenium模块用法详解

    selenium用法详解 selenium主要是用来做自动化测试,支持多种浏览器,爬虫中主要用来解决JavaScript渲染问题. 模拟浏览器进行网页加载,当requests,urllib无法正常获取 ...

  10. BZOJ3238: [Ahoi2013]差异(后缀数组)

    Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 解题思路: 看到lcp,想到了 ...