UITableview Deceleration 加速滑动(惯性滑动)、弹性回归原理

一、前言

之前做Symbian项目,由于软件的界面完全是自绘的,列表也是自绘,所以列表的滚动也要自己做,然后就试着做了两个引擎:

1.惯性滑动引擎:由于列表比较长,快速滑动,加速滑动。

2.弹性回归引擎:由于列表已经滑动到顶端(末端)需要再往下(往上)继续离开顶部(底部)一些距离,表示别表已无内容,列表到头。

当时做symbian的时候不知道Deceleration这个术语,本人只是从效果上看是惯性滑动,并且下拉的时候是回归动作。所以之前的名字是:惯性滑动,弹性回归!

基本思想就是按照每秒24帧的速度刷新列表,即每隔0.04秒刷新一次,由于是GC绘制,所以每次滑动时需要条用绘制函数,所以该引擎的效率还是不行。


这两天,将着两个引擎移植到iOS上发现,效果也不怎么滴。所以GC直接绘制效率太低。因为iOS上通常是使用“偏移量”来达到滑动效果。

相关文章: 探究contentOffset和contentInset,并解决上拉加载更多,uitableview抖动问题

二、算法思路

第一、“惯性滑动”的思路

列表较长的情况下用手拨动屏幕,实现较长的滑动。但是这个滑动又不是线性的,还要有一些阻尼效果。

所以,第一次我想到了抛物线,是源自物体掉落的轨迹,后来经过测试这个效果不好。

于是,我又想到了标准正态分布曲线,这个阻尼效果更明显。如图1所示:

UITableview Deceleration 加速滑动(惯性滑动)、弹性回归原理_第1张图片



用户拨动屏幕,当手指离开屏幕时,必然带着初速度。那么我把这个初速度对应到图1中的Y轴最高点的值,然后这个值随着时间的推移,不断减小,从而达到模拟自然情况下阻尼滑动的效果。

如何求出初速度?

设计两个长度为5的数组,一个用于记录用户滑动时的坐标Y值。另外一个用于记录时间。不管用户滑动多长距离只保留最后5个坐标和5个时间值。然后,用户滑动的距离除以时间即可算出来速度。当然这里的单位就比较模糊了(严格上说是像素/微秒)。

还有一个技术点:如果用户在屏幕上来回滑屏,即轨迹并不是一个方向。这种情况怎么判断出来。如图2所示:

UITableview Deceleration 加速滑动(惯性滑动)、弹性回归原理_第2张图片


(图2)

判断最后5个点是否在同一条直线上。

第二、再说“弹性回归”的思路。

其实弹性回归要比惯性滑动复杂。为什么?因为,惯性滑动时,具体滑动的距离我不用关心,滑动多点儿也行,少点儿也行。但是弹性回归是一个固定的距离。比如:把列表从顶端往下拉动了100个像素,那么我的弹性回归引擎,需要在一定时间内按照某个曲线正好滑动完这100个像素。这次我选的是抛物线了,下面将详细说明理由。如下图3所示:100个像素就表示图中阴影部分的面积,弹性回归引擎要


UITableview Deceleration 加速滑动(惯性滑动)、弹性回归原理_第3张图片

(图3)


根据抛物线弓形面积公式等于:以割线为底,以平行于底的切线的切点为顶点的内接三角形的3/4,即: 抛物线弓形面积=S+1/4*S+1/16*S+1/64*S+……=4/3*S

根据阴影的面积可以求出,b的值。所以,每次滑动的距离即x1,x2,x3...x(b-1)。这里x1的面积需要微积分了。

总而言之:这两个引擎核心是两个曲线,仅供参考。这个方法也让公司申请了专利。专利号CN102331877A

代码我放到:http://download.csdn.net/detail/hherima/5161117 

注意:该工程包含里富文本解析。只需要看MyListBrowserSlideEngine.m就行了。


你可能感兴趣的:(tableview,加速滑动,Deceleration,弹性回归,惯性滑动)