一 整体功能图和实现思路

1 完整的功能图:

2 实现功思路:

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

二 流水布局

1 包含下面部分:

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

2 下面是未封装的代码:

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

三 UICollectionView对象创建与相关设置

1 包含下面部分:

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

2 下面是未封装的代码:

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

四 数据源方法

1 包含下面部分:

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

2 代码部分:

  1. #pragma mark - 数据源方法(组数,不写默认为一组)
  2. - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
  3. {
  4. return 1;
  5. }
  6. #pragma mark - cell的个数
  7. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
  8. {
  9. return 20;
  10. }
  11. #pragma mark - 每一个cell的内容
  12. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
  13. {
  14. //去缓存池中找
  15. XFJFlowCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
  16. NSString *imageName = [NSString stringWithFormat:@"%zd",indexPath.row + 1];
  17. cell.image = [UIImage imageNamed:imageName];
  18. return cell;
  19. }

五 自己定义cell

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

2 定义一个图片属性

  1. @property (nonatomic, strong) UIImage *image;

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

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

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

  1. - (void)setImage:(UIImage *)image
  2. {
  3. _image = image;
  4. self.imageView.image = image;
  5. }

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

六 注冊

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

2 代码部分:

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

七 自己定义流水布局

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

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

3 照片的缩放

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

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

代码部分:

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

4 照片定位功能

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

详细的代码:

  1. //手指离开,拖动完毕的时候调用
  2. - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
  3. {
  4. //获取collectionView的宽度
  5. CGFloat width = self.collectionView.bounds.size.width;
  6. //获取终于显示区域
  7. CGRect targetR = CGRectMake(proposedContentOffset.x, 0, width, MAXFLOAT);
  8. //获取终于显示的cell
  9. NSArray *atts = [super layoutAttributesForElementsInRect:targetR];
  10. //获取cell离中心点的距离
  11. //定义一个变量记录最小的中心距离
  12. CGFloat minDelta = MAXFLOAT;
  13. for (UICollectionViewLayoutAttributes *att in atts) {
  14. //获取中心距离
  15. CGFloat delta = att.center.x - (width * 0.5 + proposedContentOffset.x);
  16. //推断
  17. if (fabs(delta) < fabs(minDelta)) {
  18. minDelta = delta;
  19. }
  20. }
  21. //终于的偏移量加上离中心点的距离
  22. proposedContentOffset.x += minDelta;
  23. //推断,假设终于的偏移量小于0
  24. if (proposedContentOffset.x < 0) {
  25. proposedContentOffset.x = 0;
  26. }
  27. return proposedContentOffset;
  28. }

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

八 前提

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

1 仅仅要滚动就会刷新

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

九 新的封装方法

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

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

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

2.1 封装代码块一:

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

2.2 封装代码块二:

  1. //封装二:
  2. //创建UICollectionView
  3. UICollectionView *collectionView = ({
  4. UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
  5. //bounds
  6. collectionView.bounds = CGRectMake(XFJ_zero, XFJ_zero, self.view.bounds.size.width, 200);
  7. //center
  8. collectionView.center = self.view.center;
  9. //隐藏底部的滚动栏
  10. collectionView.showsHorizontalScrollIndicator = NO;
  11. //设置背景颜色
  12. collectionView.backgroundColor = [UIColor brownColor];
  13. //加入到控制器的view中
  14. [self.view addSubview:collectionView];
  15. //设置代理
  16. collectionView.dataSource = self;
  17. //取的是最后的值
  18. collectionView;
  19. });

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. Easy mock - 安装配置和基本使用

    Easy-mock easy-mock是一款比较好用的接口模拟工具, 使用之前我们需要安装和配置 需要下载的内容有以下 Node Redis MongoDB Node和Redis一路点下一步就行, M ...

  2. ManagementObjectSearcher 对象获取串口列表

    首先,需引用using System.Management; 可先建个枚举类,如下 #region WIN32 API /// <summary> /// 枚举win32 api /// ...

  3. Eclipse怎样把文件系统形式的项目作为工程直接导入?

    导入的时候,选择已经存在的工程,如果选择文件系统,可能会提示没有项目可以导入.这个时候,可以从其它Eclipse项目下,copy一份.project文件过来,修改源文件中的工程名字.如果需要,也可以c ...

  4. Webservice银行报文接口设计

      Preface: 合理的软件架构设计其好处是不言而喻的,系统具有清晰的软件结构,良好的可扩展性,类的职能单一明确,系统的复杂度底.此前的一个实际项目中总结了些关于OO设计的实际应用,主要是围绕'高 ...

  5. HDU 5063 Operation the Sequence(暴力 数学)

    题目链接:pid=5063" target="_blank">http://acm.hdu.edu.cn/showproblem.php?pid=5063 Prob ...

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

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

  7. 计蒜客 429(腾讯手机地图-pi的精确值)

    腾讯手机地图的定位功能用到了用户手机的多种信号.这当中有的信号的作用范围近.有的信号作用的范围则远一些.有的信号相对于用户在不同的方位强度是不同的.有的则是在不论什么一个方向上信号强度都一致的. 已知 ...

  8. 单位阶跃函数(Heaviside/unit step function)—— 化简分段函数

    注意,单位阶跃函数一种不连续函数. 1. 常见定义 最经典的定义来自于 Ramp function(斜坡函数,max{x,0})的微分形式: H(x)=ddxmax{x,0} 2. 化简分段函数 如对 ...

  9. vue ---webpack 打包上线

     先来描述一下期间遇到的问题有哪些: 1.打包后将 dist 文件夹和 index.html 放到 tomcat,在浏览器中访问时,出现空白页,f12 提示 404. 2.打包好的静态资源均是绝对路径 ...

  10. 词向量 word2vec

    看的这一篇的笔记 http://licstar.net/archives/328 看不太懂. 要学的话,看这里吧,这里把一些资料做了整合: http://www.cnblogs.com/wuzhitj ...