垂直滚动选择效果的实现

概述

这是一个在垂直方向上滚动的控件,用于单选。

详细

 

一、程序实现

1、项目结构图

他.png

2、实现思路

这个是利用tableView来实现的,中间的两条线放在tableView的上面并且与tableView同级别,这样在tableView滚动的时候,这两条线可以一直固定着不动。

线的位置:首先可以把两条线的闭合区域当做是一个view,我们是希望这个view用来展示每个高亮的cell,所以这个view的高度必须是跟cell的高度一致。而且我们希望这个view在tableView的中间位置。所以这个view的位置应该是这样的位置:

 

整个tableView的cell分为两类:一类是上图中的空白部分,这个只要由系统提供的cell实现就可以;一类是我们要用来显示选项的cell,这个cell我们采用自定义的cell来实现,下面统一叫做typeCell。那么在numberOfRow方法里面是这么设置的。

- (NSInteger)tableView:(UITableView *)tableViewnumberOfRowsInSection:(NSInteger)section{
returnself.dataSource.count+2;
}

综合得知,整个tableView的contentSize应该是

dataSouce.count*cellH + (tableViewH - cellH)

滚动显示

接下来应该是比较重要的,就是我们如何在滚动tableView的时候,能让中间的view显示且高亮显示待选项。

这里UIScrollViewDelegate的几个方法。

//这个方法主要用来在滚动的时候切换高亮显示
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;

//下面两个方法用于当tableView在中间view的显示不是刚好一个cell的时候,强制设置偏移量,使得中间view刚好显示一个完整的cell,规则是当cell一半或以上在中间view的时候,中间view就显示这个cell。
//用于手指触摸松开后不再滚动(这个方法在手指触摸并滚动后松开后有两种情况:继续滚动or停止)
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollViewwillDecelerate:(BOOL)decelerate;

//用于手指触摸并滚动后松开后还在滚动的处理
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

这里最重要的地方就是如何通过tableView的偏移量来计算当前要在中间view显示的是哪个cell的问题。下面我们来讲讲这个问题,这里分三种情况来讨论(tableView的偏移量我们用offsetY来表示,typeCellH来表示typCell的高度):

1.中间view要显示第一个typeCell时,这时offsetY要小于等于typeCellH/2;
2.中间view要显示最后一个typeCell时,这时最后一个typeCell的frameY应该要在中间view的中间位置上,如下图。这个时候,倒数第二个typeCell还有一半在中间view显示,offsetY应该要等于(dataSource.count-1)*typeCellH-typeCellH/2。而这个时候offsetY如果再大,肯定只能显示最后的这个typeCell。所以第二个情况来说,

offsetY>=(dataSource.count-1)*typeCellH-typeCellH/2

3.中间view要显示中间部分的typeCell。我们先来用模型看下:

假设typeCellH = 10,要显示5个typeCell
那么除去情况1和2,所以我们考虑要显示的typeCell是从1,2,3。

显示1时,offsetY的取值范围为:[6,15]; 0.1-1
显示2时,offsetY的取值范围为:[16,25];1.1-2
显示3时,offsetY的取值范围为:[26,35];2.1-3

所以我们可以得出一个公式:

typeCellH/2 + 1 + typeCellH * (dataIndex - 1) <= offsetY <= typeCellH/2 + 1 + typeCellH *dataIndex
dataIndex即为我们要高亮显示的typeCell在dataSource对应的索引

然后从这个公式我们可以得到下面这个式子:

dataIndex - 1 <= (offsetY-typeCellH/2-1)/typeCellH<= dataIndex

所以我们可以先计算(offsetY-typeCellH/2-1)/typeCellH的值,记为temp,然后对temp向上取整,即ceil(temp),这样就可以求得dataIndex。

所以根据上面三种情况,我们可以求得中间view高亮显示的是dataSource里面对应元素得索引dataIndex。然后我们就可以将tableView的offsetY设置为dataIndex*typeCellH。这样当tableView的offsetY无论在哪里,我们都可以在中间view完整的显示适当的typeCell。

二、运行效果

1909966-038235b55d150957.gif

 

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

posted on   demo例子集  阅读(439)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示