垂直滚动选择效果的实现
概述
详细
一、程序实现
1、项目结构图
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。
二、运行效果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?