【iOS系列】- iOS吸附效果的实现 之 UICollectionView的使用全解
【iOS系列】- iOS吸附效果的实现 之 UICollectionView的使用全解
UICollectionView可以做很多的布局,在iOS开发中较为重要,所以这里就以实例来讲解UICollectionView的使用进阶。
注: 用StoryBoard拖出来的UICollectionView的布局就是流水布局,无法修改,所以如果要实现一些自定义的效果需要通过代码创建UICollectionView
项目示例如下:效果为吸附的效果,App Store中也有类似的效果,就是单元格出来小于一半:则就让其回退;如果大于一半:则就让其直接移出界面显示区域:

Demo下载地址:iOS_Demo
一些概念
UICollectionView中有个重要的内容UICollectionViewLayout,UICollectionView的显示是由其布局文件决定的。
UICollectionViewFlowLayout:系统提供的流水布局,如果要自定义流水布局的效果可以自定义这个类。
布局决定每一个cell的尺寸,位置,间距等等。
每一个cell/item都有自己UICollectionViewLayoutAttributes
每一个indexPath也都有自己UICollectionViewLayoutAttributes
开始
所以这次做的吸附效果也完全是自定义了UICollectionViewFlowLayout,
下面对这个类的主要方法进行大体介绍:
prepareLayout:一些初始化的工作最好这里完成,比如item的大小等等-(void)prepareLayout
{
[super prepareLayout];//需要调用super方法 //初始化
self.itemSize = CGSizeMake(90, 90);//设置item的大小
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;//设置滚动防线
self.minimumLineSpacing = 10;//设置cell的间距
self.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);//设置四周的间距
}
targetContentOffsetForProposedContentOffset:控制控制最后UICollectionView的最后去哪里,我们这里需要做的吸附效果的逻辑代码就需要在这里完成。参数介绍proposedContentOffset:原本UICollectionView停止滚动那一刻的位置;velocity:滚动速度-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
//TODO
}
shouldInvalidateLayoutForBoundsChange:边界发生改变时,是否需要重新布局,返回YES就需要重新布局(会自动调用layoutAttributesForElementsInRect方法,获得所有cell的布局属性)-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}layoutAttributesForElementsInRect:返回所有cell的布局属性-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
return [super layoutAttributesForElementsInRect:rect];
}
方法介绍完毕,我们在prepareLayout
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
//1.计算scrollview最后停留的范围
CGRect lastRect ;
lastRect.origin = proposedContentOffset;
lastRect.size = self.collectionView.frame.size;
//2.取出这个范围内的所有属性
NSArray *array = [self layoutAttributesForElementsInRect:lastRect];
//起始的x值,也即默认情况下要停下来的x值
CGFloat startX = proposedContentOffset.x;
//3.遍历所有的属性
CGFloat adjustOffsetX = MAXFLOAT;
for (UICollectionViewLayoutAttributes *attrs in array) {
CGFloat attrsX = CGRectGetMinX(attrs.frame);
CGFloat attrsW = CGRectGetWidth(attrs.frame) ;
if (startX - attrsX < attrsW/2) {
adjustOffsetX = -(startX - attrsX+ItemMaigin);
}else{
adjustOffsetX = attrsW - (startX - attrsX);
}
break ;//只循环数组中第一个元素即可,所以直接break了
}
return CGPointMake(proposedContentOffset.x + adjustOffsetX, proposedContentOffset.y);
}
这样我们要做的吸附效果的Layout文件就完成了。
我们在初始化UICollectionView的时候选择带有Layout参数的init方法即可。
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:rect collectionViewLayout:viscosityLayout];
Demo地址:iOS_Demo-自定义UICollectionView的布局
Demo下载地址:iOS_Demo
注:把Demo中的ViewController.m的33行
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:rect collectionViewLayout:viscosityLayout];
改成//具体初始化的逻辑已经实现了。
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:rect collectionViewLayout:flowLayout];
即可实现下图所示的效果(cell滚动的时候,中间会慢慢变大,也有吸附效果,不过在最中心的cell才会吸附在中心),具体做法是在layoutAttributesForElementsInRect方法中修复了布局属性,可下载Demo自行查看。

作者:Darren
微博:@IT_攻城师
github:@Darren90
博客:http://www.cnblogs.com/fengtengfei/
欢迎您的访问...
【iOS系列】- iOS吸附效果的实现 之 UICollectionView的使用全解的更多相关文章
- [Android开发学iOS系列] iOS写UI的几种方式
[Android开发学iOS系列] iOS写UI的几种方式 作为一个现代化的平台, iOS的发展也经历了好几个时代. 本文讲讲iOS写UI的几种主要方式和各自的特点. iOS写UI的方式 在iOS中写 ...
- jquery系列教程4-事件操作全解
点击打开: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件操作全解 jquery系列教程5-动 ...
- jquery系列教程2-style样式操作全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件 ...
- iOS系列 基础篇 06 标签和按钮 (Label & Button)
iOS系列 基础篇 06 标签和按钮 (Label & Button) 目录: 标签控件 按钮控件 小结 标签和按钮是两个常用的控件,下面咱们逐一学习. 1. 标签控件 使用Single Vi ...
- iOS系列 基础篇 07 Action动作和输出口
iOS系列 基础篇 07 Action动作和输出口 目录: 1. 前言及案例说明 2. 什么是动作? 3. 什么是输出口? 4. 实战 5. 结尾 1. 前言及案例说明 上篇内容我们学习了标签和按钮 ...
- iOS系列 基础篇 08 文本与键盘
iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...
- iOS系列 基础篇 09 开关、滑块和分段控件
iOS系列 基础篇 09 开关.滑块和分段控件 目录: 案例说明 开关控件Switch 滑块控件Slider 分段控件Segmented Control 1. 案例说明 开关控件(Switch).滑块 ...
- 【iOS系列】-自定义Modar动画
[iOS系列]-自定义Modar动画.md 我们需要做的最终的modar动画的效果是这样的, 就是点击cell,cell发生位移,慢慢的到第二个界面上的.为了做出这样的动画效果,我们需要以下的知识. ...
- 【iOS系列】-UIWebView加载网页禁止左右滑动
[iOS系列]-UIWebView加载网页禁止左右滑动 问题: 做项目时候,用UIWebView加载网页的时候,要求是和微信网页中打开的网页的效果一样,也即是只能上下滑动,不能左右滑动,也不能缩放. ...
随机推荐
- [LOJ] 分块九题 4
https://loj.ac/problem/6280 区间修改,区间求和. 本来线段树的活. //Stay foolish,stay hungry,stay young,stay simple #i ...
- docker使用阿里云镜像仓库docker
1:阿里云docker仓库 https://dev.aliyun.com/search.html 2:进去注册帐号后,点击自己的管理中心. 3:在管理中心点击加速器,右边面板会有你的加速地址,右边面板 ...
- maven打包oracle jdbc驱动
背景 由于版权问题,maven中央仓库缺少oracle jdbc的驱动,这个给开发带来了很多不便利性.也出现各种各样的解决方案,基本就两种思路: 将oracle驱动安装到本地仓库,这个需要大家统一好名 ...
- 第四讲:debugging simulation mismatches
关于竞争冒险: 1.use +race utility to locate race condition code **** 2.use $vcdplusdeltacycleon to locate ...
- Android开发——查询/杀死手机里正在运行的进程
0. 前言 以前有同学好像做过一个叫"自习君"的App,开启后自动检测用户这一天的自习时间,在学校里宣传广告还打了不少.其实实现原理非常简单,在SQlite数据库(也可以通过文件) ...
- Go切片的操作
package main import "fmt" //切片的操作 func main() { //创建slice var s []int //zero value for sli ...
- ArrayList去除重复元素
去除一个ArrayList的重复元素有两种方法:(ArrayList与Vector的存储结构是Object[],LinkedList是双向列表) 第一种是不需要借助临时list,用equals方法比较 ...
- msp430入门编程47
msp430中C语言的人机交互--菜单退出 msp430入门编程 msp430入门学习
- php中memcache与memcached的区别 【收藏】
说法一: 两个不同版本的php的memcached的客户端 new memcache是pecl扩展库版本new memcached是libmemcached版本功能差不多 说法二: Mem ...
- iOS远程推送原理
远程推送 就是从远程server推送消息给client的通知.当然须要联网. 远程推送服务APNs (Apple Push NotificationServices) 为什么须要远程推送通知? 传统获 ...