一 整体功能图和实现思路

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. vue prpos

    匹配某些值中的一个 type: { validator: function(value) { return ["success", "warning", &qu ...

  2. 小米开源文件管理器MiCodeFileExplorer-源码研究(6)-媒体文件MediaFile和文件类型MimeUtils

    接着之前的第4篇,本篇的2个类,仍然是工具类.MediaFile,媒体文件,定义了一大堆的常量,真正的有用的方法就几个.isAudioFileType.isVideoFileType之类的. Mime ...

  3. 【2017 Multi-University Training Contest - Team 4】Counting Divisors

    [Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6069 [Description] 定义d(i)为数字i的因子个数; 求∑rld(ik) 其中l,r ...

  4. C# wpf程序获取当前程序版本

    C# wpf程序获取当前程序版本 /// <summary>         /// 获取当前系统的版本         /// </summary>         /// ...

  5. eclipse - 下载网址

    这里面有着非常齐全的eclipse相关资源,而且都是放在网盘里面的,下载也方便 http://www.androiddevtools.cn/

  6. [LuoguP4892]GodFly的寻宝之旅 状压DP

    链接 基础状压DP,预处理出sum,按照题意模拟即可 复杂度 \(O(n^22^n)\) #include<bits/stdc++.h> #define REP(i,a,b) for(in ...

  7. golang sync.Mutex(2)

    package main import ( "fmt" "sync" "time" ) type User struct { Name st ...

  8. [React] Render Elements Outside the Current React Tree using Portals in React 16

    By default the React Component Tree directly maps to the DOM Tree. In some cases when you have UI el ...

  9. Android滚轮选择器实现

    思路: 1.布局,整个控件的布局,事实上就是用代码取带xml来实现当前布局 2,能够滑动的(即滚轮).事实上是一个ScrollView 3.推断滑动状态的,有protected void onScro ...

  10. Event Serializers官网剖析(博主推荐)

    不多说,直接上干货! Flume Sources官网剖析(博主推荐) Flume Channels官网剖析(博主推荐) Flume Channel Selectors官网剖析(博主推荐) Flume ...