• 垂直滚动选择效果的实现


    概述

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

    详细

    一、程序实现

    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大师发表,拒绝转载,转载需要作者授权

  • 相关阅读:
    IE input X 去掉文本框的叉叉和密码输入框的眼睛图标
    vue监听滚动事件 实现某元素吸顶或者固定位置显示
    判断滚动条到底部的JS逻辑
    vue plugin 插件编写以loading为例
    Maven使用yuicompressor-maven-plugin打包压缩css、js文件
    AngularJS 用 Interceptors 来统一处理 HTTP 请求和响应
    jQuery mouseover与mouseenter,mouseout与mouseleave的区别
    angular内ng存在属性是专门用来解决跨域问题的,$sce
    dede上怎么让所有链接在新窗口打开
    dede文章页调用当前栏目链接方法
  • 原文地址:https://www.cnblogs.com/demodashi/p/8491113.html
Copyright © 2020-2023  润新知