无限循环滚动控件的思路

无限滚动场景还是很常见的,例如无限banner滚动,还有我要实现的无限向上滚动的需求:

2018-02-08 14_58_00.gif

可以确定,这种滚动效果,需要用tableView(或者UICollectionView,或者更底层一点的UIScrollView)实现,主要问题是,当滚动到最后一个的时候,怎么继续滚动到第一个,循环滚动下去。

有两种实现思路:一个是,设置一个很大的数据源,当然实际的数据可能只有两条,我们不断重复的设置,例如,你的数据是三个,分别为a,b,c。那么你的数据源是a,b,c,a,b,c,a,b,c,a...可以设置一个巨大的数据源,以保证,在一定的时间内绝对不会滚到最后一个。

这种实现从内存和效率上,都不会有问题,只是不那么优雅!因为a,b,c不断的重复,在数据源数组里,只不过是引用而已,实际永远只有a,b,c这三个元素,内存不会增加,另外,因为UITableView的Cell重用机制保证,你无论TableView有多长,实际永远只有可见的那个Cell会占用内存和CPU绘制资源。所以,无论内存还是效率都不会有问题。

左右一个有追求的程序员,当然不能容忍这种不优雅的实现!

还是以a,b,c为例来阐述第二种思路,我会将数据源设置为c,a,b,c,可以看到,我多添加了一个数据源,将最后一个数据源又插入了第一位。页面开始展示的时候,我会将tableView定位到a,然后依次滚动,当滚动到最后一位c的时候,我会瞬间变到第一位的c,因为第四位到第一位的变化是瞬间的,且数据源是一样的,所以,根本看不出来这个瞬间的变化。然后,继续从第一位的c,继续滚动到a,这样就造成了一种循环滚动的错觉。

下面是实现代码:

if self.curIndexPath.row < self.dataSource.count {
                    self.tableView.scrollToRow(at: self.curIndexPath, at: UITableViewScrollPosition.middle, animated: true)
                    self.curIndexPath = IndexPath(row: self.curIndexPath.row + 1, section: 0)
                } else if self.curIndexPath.row == self.dataSource.count {//最后一行
                    //瞬间滚动到第一行,所谓瞬间是这里的动画设置为false
                    self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: UITableViewScrollPosition.middle, animated: false)

                    self.curIndexPath = IndexPath(row: 1, section: 0)
                    //瞬间到第一行后,继续滚动
                    self.tableView.scrollToRow(at: self.curIndexPath, at: UITableViewScrollPosition.middle, animated: true)
                    self.curIndexPath = IndexPath(row: self.curIndexPath.row + 1, section: 0)
                }

例子代码

你可能感兴趣的:(无限循环滚动控件的思路)