垂直滚动选择效果的实现

概述

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

详细

一、程序实现

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。

二、运行效果

垂直滚动选择效果的实现


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