CollectionView缩放水平卡片布局
实现效果
实现思路
从Demo效果图中,可以看出来,主要是缩放系数的计算。对于不同距离的cell,其缩放系数要变化,以便整体协调显示。
所以,我们必须重写-layoutAttributesForElementsInRect:方法来实现所有当前可见的cell的attributes。
计算比例,通过获取当前偏移rect的最小坐标x,再与atribute的中心x相减,再除以高度,就是高度的缩放倍数scaleForDistance。
最后,通过一个公式来计算缩放的Y系数。公式为:
1
2
3
|
scale = 1 + scaleFactor * (1 - fabs(scaleForDistance))
|
scaleFactor因子可以自由调整,值越大,显示就越大。
核心代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#pragma mark - Override
- (void)prepareLayout {
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.minimumLineSpacing = 20;
// self.minimumInteritemSpacing = 20;
self.sectionInset = UIEdgeInsetsMake(0, 30, 0, 30);
self.itemSize = CGSizeMake(self.collectionView.frame.size.width - 60,
self.collectionView.frame.size.height - 180);
[super prepareLayout];
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *superAttributes = [super layoutAttributesForElementsInRect:rect];
NSArray *attributes = [[NSArray alloc] initWithArray:superAttributes copyItems:YES];
CGRect visibleRect = CGRectMake(self.collectionView.contentOffset.x,
self.collectionView.contentOffset.y,
self.collectionView.frame.size.width,
self.collectionView.frame.size.height);
CGFloat offset = CGRectGetMidX(visibleRect);
[attributes enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attribute, NSUInteger idx, BOOL * _Nonnull stop) {
CGFloat distance = offset - attribute.center.x;
// 越往中心移动,值越小,那么缩放就越小,从而显示就越大
// 同样,超过中心后,越往左、右走,缩放就越大,显示就越小
CGFloat scaleForDistance = distance / self.itemSize.height;
// 0.2可调整,值越大,显示就越大
CGFloat scaleForCell = 1 + 0.2 * (1 - fabs(scaleForDistance));
// only scale y-axis
attribute.transform3D = CATransform3DMakeScale(1, scaleForCell, 1);
attribute.zIndex = 1;
}];
return attributes;
}
|
实现pagingEnabled的样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
BOOL pagingEnabled = NO;
if (pagingEnabled) {
// 分页以1/3处
if (proposedContentOffset.x > self.previousOffsetX + self.itemSize.width / 3.0) {
self.previousOffsetX += self.collectionView.frame.size.width - self.minimumLineSpacing * 2;
} else if (proposedContentOffset.x < self.previousOffsetX - self.itemSize.width / 3.0) {
self.previousOffsetX -= self.collectionView.frame.size.width - self.minimumLineSpacing * 2;
}
proposedContentOffset.x = self.previousOffsetX;
} else {
CGFloat x = proposedContentOffset.x / (self.itemSize.width + self.minimumLineSpacing);
int base = (int)x;
proposedContentOffset.x = base * (self.itemSize.width + self.minimumLineSpacing);
}
return proposedContentOffset;
}
|
这里是以1/3.0为分界,左、右的1/3作为分界线,超过才会切换过去!
感谢
感谢评论的朋友们的一句话,点醒了笔者。对于不分页的情况下,其实只要使用当前的偏移x除(itemSize.width + minimumLineSpacing)就得到一个倍数,然后四舍五入。比如,4.3取整得到4,那么就是没有超过一半,就要往回滚。而4.6取整得到5,表示要滚动到下一个。所以在不分页的情况下,其实也是非常简单的。
CollectionView缩放水平卡片布局的更多相关文章
- CollectionView旋转水平卡片布局
概述 UICollectionView真的好强大,今天我们来研究一下这种很常见的卡片动画效果是如何实现了.本篇不能太深入地讲解,因为笔者也是刚刚摸索出点眉目,但是并没有深刻地理解.如果在讲解过程中,出 ...
- Java基础之创建窗口——使用卡片布局管理器(TryCardLayout)
控制台程序. 卡片布局管理器会生成一叠组件——一个组件放在另一个组件的上面.添加到容器中的第一个组件在堆栈的顶部,因此是可见的,添加的最后一个组件在堆栈的底部.使用默认的构造函数CardLayout( ...
- 转:三十二、Java图形化界面设计——布局管理器之CardLayout(卡片布局)
转:http://blog.csdn.net/liujun13579/article/details/7773945 卡片布局能够让多个组件共享同一个显示空间,共享空间的组件之间的关系就像一叠牌,组件 ...
- 三十二、Java图形化界面设计——布局管理器之CardLayout(卡片布局)
摘自 http://blog.csdn.net/liujun13579/article/details/7773945 三十二.Java图形化界面设计--布局管理器之CardLayout(卡片布局) ...
- 布局管理器之CardLayout(卡片布局管理器)
对于选项卡这个概念大家可能不会陌生,就是在一个窗口中可以切换显示多页不同的内容,但同一时间只能是其中的某一页可见的,这样的一个个的页面就是选项卡. CardLayout就是类似的这样一个布局管理器,它 ...
- 技术胖Flutter第三季-18布局CardWidget 卡片布局组件
技术胖Flutter第三季-18布局CardWidget 卡片布局组件 博客地址: https://jspang.com/post/flutter3.html#toc-420 最外面是Card布局,里 ...
- 慕课网5-2编程练习:flex布局制作卡片布局案例
慕课网5-2编程练习:flex布局制作卡片布局案例 小伙伴们,学习了卡片布局,接下来我们根据效果图,也写出一个卡片布局的页面吧! 效果图如下: 任务 1.主体内容的卡片一行只能显示两个. 2.卡片与卡 ...
- CollectionView垂直缩放卡片布局
实现效果 实现思路 从效果图可以看到变化是,越是往中间滚动的item显示最大,越显眼.而越是往前面,或者越是后面的,反而显示越小,这样就形成了视觉差. 实现的思路就是通过重写在可见范围内的所有item ...
- java 图形化小工具Abstract Window Toolit ;布局管理器FlowLayout流式布局;BorderLayout边界布局;GridLayout网格布局;CardLayou重叠卡片布局;BoxLayout方框布局;绝对定位
1.FlowLayout流式布局管理器: FlowLayout布局管理器中,组件像水流一样向某方向流动(排列),遇到障碍(边界)就折回,重头开始排列 .在默认情况下,FlowLayout局管理器从左向 ...
随机推荐
- php基础语句 变量 符号
中心主题 标记与注释 // /* */ 输出语句 echo输出 echo可以输出多个字符串,逗号隔开 print输出 print只能输出一个字符串,返回true或false print_r() 可以把 ...
- BZOJ1592: [Usaco2008 Feb]Making the Grade 路面修整
n<=2000个数,把它修改成不上升或不下降序列所要改变的数值总共最小是多少yy一下可得最后改成的数值肯定是原数组数值中的某一个感觉一下,相邻两个数如果有冲突要改,那肯定把他们改成两者之一的数才 ...
- hihoCoder #1067 : 最近公共祖先·二 [ 离线LCA tarjan ]
传送门: #1067 : 最近公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站 ...
- HTTP请求示例
HTTP请求格式 当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成: l 请求方法URI协议/版本 l 请求头(Request Hea ...
- HDU 2059 【DP】
题意: 中文. 思路: 这题不是自己的思想. 当对第i个点的最优值进行求解的时候一定存在最后一个加油的点j.这里j直接枚举. 另外将0和n+1个加油站定义为起点和终点. dp需要加强训练. #incl ...
- IOCP数据中间件
IOCP数据中间件 每包最大8K(8192字节),超过8187字节的数据要分包传输 首包有5个字节的包头:4字节数据长度(告诉对方,此次总共将传输几字节数据) + 1字节命令字(告诉对方,此次请求的何 ...
- 关闭Windows 2003/2008中IE增强的安全配置的方法
在使用Windows Server 2003/2008操作系统时,打开IE浏览网页时,发现浏览器总提示 "是否需要将当前访问的网站添加到自己信任的站点中去",要是不信 ...
- Android切图注意事项
1.App Logo大小共五种: 48*48 72*72 96*96 144*144 192*192 2. App启动页所需尺寸: 320×480 480×800 720*1280 1080*1920 ...
- Android开发艺术-第二章 IPC 机制
2.1 Android IPC 简单介绍 IPC 意为进程间通信或者跨进程通信,线程是 CPU 调度的最小单元,是一种有限的系统资源. 进程一般指一个执行单元.不论什么操作系统都须要对应的 IPC 机 ...
- Angular2.x-主/细节组件
此刻,HeroesComponent显示heroes列表和所选heroes的详细信息. 随着应用程序的增长保持一个组件中的所有功能将不可维护.您需要将大型组件分成更小的子组件,每个组件都专注于特定的任 ...