文档章节

iOS换一种思路写一个无限轮播的滚动视图

iShown
 iShown
发布于 2016/11/17 12:34
字数 1202
阅读 592
收藏 0

不循环设置元数据,只用3个cell,连续滚动一辈子滚不到头???

哈哈哈,不开玩笑,你值得拥有 写这篇博客已经距离我当时写轮子差不多有一个月时间了,也完善了很多,基本是没有bug的,如果有,不妨留言,喜欢的话,劳烦各位点个赞,不喜欢的,不妨看看思路,提提意见 ##github地址 ##码云地址

###1. 以前的思路使用scrollView 基本是以下的方法

a,使用scrollView放轮播图,scroll分页放置图片可以实现左右轮播

b,在头尾各添加两个图片,然后在滑动到最后一张的时候处理滑动

例如123一共3张图片

加两个形成31231一共5张图片

c,当滑动到最后一张时候如何再往右滑动,瞬间无动画切换到起始位置的呢一张图,第一张往左滑动也同样处理

d,处理手动和定时器

scroll实现轮播图链接

###2.最近流行的使用collection 使用collectionView可以很方便的创建轮播图,并且利用collectionViewCell的复用,很方便的管理,原理也很简单

a,把轮播图的元数据扩大,123123123...123123123

b,创建视图把初始位置设置为中间点

c,处理滚动到头时候

如此基本可以解决问题,如果害怕滑动到头一般设置为9999

这里一般会优化数据源, 使用123,在读取时候循环读取

###3.自己的想法和优雅的点子

####想法1,数据源的读取并不优雅

数据源是个很明显的双向循环,这个结构跟以前"听说"的双向链表那么的契合,为什么不使用双向链表作为数据源呢

####想法2,collection设置99999真的的好么,表示我是一个崇尚优雅的猿

本来就是轮播嘛,滑动的时候怎么左右滚,划,总不会需要超过3个的cell吧

####Then-> 假如我有一个链表,假如我只使用3个cell,那么我可以写成一个循环滚动的轮播图吗

####原理应该是 每次滑动结束之后就回到中间的那一张

左划3个cell的数据源整体向左,右划类推

###4,想法是不够的,轮子才是我想要的

####循环链表??...面向对象大发好

设置每一个数据

@interface SXLinkList : NSObject
@property(nonatomic, assign) NSInteger index;
@property(nonatomic, strong) id data;
@property(nonatomic, strong) SXLinkList *next;
@property(nonatomic, strong) SXLinkList *last;
@end

把数据联系起来,用for循环创建,然后把头和尾接起来

+ (SXLinkList *)createLinkListWithURLsArray:(NSArray *)urlArr {
//第一只
    SXLinkList *head = [[SXLinkList alloc] init];
    head.data = [urlArr firstObject];
    head.index = 0;
    SXLinkList *ptr = head;
    for (int i=1; i<urlArr.count; i++){
        SXLinkList *node = [[SXLinkList alloc] init];
        node.index = i;
        node.data = [urlArr objectAtIndex:i];
        ptr.next = node;
        node.last = ptr;
        ptr = node;
    }
//穿起来
    head.last = ptr;
    ptr.next = head;
    return head;
}

然后创建了collectionView什么的就很随意的,个数呢,拒绝9,我们只要3

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 3;
}

问题总是不经意的出现: 怎么判断左划还是又滑?

设置一个参数看是否滑动成功,成功则对比知道左右划,然后切换数据

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    SXCycleCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"SXCycleCollectionCell" forIndexPath:indexPath];
    
    if (!_isMove) {
        _isMove = YES;
        _nowPtr = _ptr;
    }
    if (indexPath.row == 0) {
        _ptr = _nowPtr.last;
    } else if (indexPath.row == 2) {
        _ptr = _nowPtr.next;
    }
    if (_isLocalImage) {
        [cell setCellData:_ptr.data];
    } else {
        [cell setCellImageIsUrlData:_ptr.data];
    }
    
    return cell;
}

然后切换到下标为1的cell

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.x <= 0 || scrollView.contentOffset.x >= 2 * self.bounds.size.width) {
        _isMove = NO;                                                                     //重置是否移动
        [scrollView setContentOffset:CGPointMake(self.bounds.size.width, 0) animated:NO]; //切换到下标1的cell
    }
}

#####如此基本搞定!然而运行发现有个bug,慢速的滑动没有问题,快速的滑动会因为cell还没有被回收,会闪一下然后正常,所以不得不手动处理这个bug,所有上边的方法修改为下边

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    //tableViewCell的复用会延缓一点点时间,手动设置以防止没有复用的时候显示错误
    if (scrollView.contentOffset.x <= 0 || scrollView.contentOffset.x >= 2 * self.bounds.size.width) {
        _isMove = NO;                                                                     //重置是否移动
        [scrollView setContentOffset:CGPointMake(self.bounds.size.width, 0) animated:NO]; //切换到下标1的cell
        //更新cell的值(滑动过快时候cell没有回收复用)
        SXCycleCollectionCell *cell = (SXCycleCollectionCell *) [self.mainView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
        if (_isLocalImage) {
            [cell setCellData:_ptr.data];
        } else {
            [cell setCellImageIsUrlData:_ptr.data];
        }
        _pageControl.currentPage = _ptr.index;
    }
}

最后设置定时器,添加本地图片,封装类方法

上图 图片

欢迎提意见

© 著作权归作者所有

iShown
粉丝 16
博文 67
码字总数 46936
作品 0
浦东
高级程序员
私信 提问
加载中

评论(1)

S
ScorpioJ
66666
iOS多种刷新样式、音乐播放器、仿抖音视频、旅游App等源码

iOS精选源码 企业级开源项目,模仿艺龙旅行App(http://www.code4app.com/thread-14774-1-1.html) 3D立体相册,可以旋转的立方体(http://www.code4app.com/thread-14966-1-1.html) 横竖屏切换...

Android爱开源
2018/10/17
0
0
h5实现视频手势上下屏滑动(类似抖音)

1. 首先考虑无限滑动的实现,最初的第一反应,是用竖向的轮播来实现。 这里要考虑的是如何实现无缝衔接~ 是否开启无限循环 我是这样实现的,总共轮播有三帧,所以特殊的是前两张和没有后续数...

天上月丶
05/21
0
0
MUI在Android与IOS上的一些小问题以及一些框架的用法

我费话少说,上正文; 区域滚动与下拉刷新、上拉加载在安卓上有冲突,一但调用了区域滚动也就是: 那么区域滚动在安卓上将无法滑动,iOS则没有影响。 并且就算iOS没有初始化区域滚动也没有影...

教父君
2018/11/07
0
0
企鹅电竞weex实践——UI开发篇

腾讯DeepOcean原创文章:dopro.io/egame-weex-… 随着电竞业务的不断发展,页面功能越来越多,交互逻辑更加复杂,类似无限滚动、上拉刷新、横竖切换滚动等形式在业务中已是标配,经过重重优化...

腾讯DeepOcean
2018/11/15
0
0
iOS简单音乐实现、React-Native完整项目、仿闲鱼京东列表分页、语音识别、网络加载过度动画等源码

iOS精选源码 iOS快速入手语音识别、听写、评测、播报 网络加载数据的过渡动画(仿简书网页) iOS 封装跑马灯和轮播效果 crash防护组件,适用常见常用的数组,字典等crash保护 iOS:高仿闲鱼、...

Code4app
2018/09/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

docker 搭建elasticsearch集群

docker 搭建es集群 1、拉去es镜像 docker pull docker.io/elasticsearch:5.6.8 2、 创建挂载目录 mkdir -p /docker/es/configmkdir -p /docker/es/data1mkdir -p /docker/es/data2......

北岩
30分钟前
2
0
Linux检测邮箱是否真实存在方法

例如我们要验证 laiconglin3@126.com 是否真实存在 nslookup -type=MX 126.com 查找126.com 的MX 地址 test@test:~$ nslookup -type=MX 126.comServer:127.0.1.1Address:127.0.1.1#53......

laiconglin
42分钟前
5
0
微人事

微人事是一个前后端分离的人力资源管理系统,项目采用SpringBoot+Vue开发。 lenve/vhr 微人事系统开源啦!

miaojiangmin
43分钟前
1
0
Mongodb 字符串转Date 计算时间间隔

$dateFromString: { dateString: '2019-07-22', timezone: 'Asia/Shanghai'}} 确定好字符串和时区即可 计算时间间隔 $subtract:[{$dateFromString: {dateString: '2019-07-2......

可达鸭Go
45分钟前
4
0
新建Git仓库并添加本地项目

新建Git仓库并添加本地项目 1、在自己的GitHub上创建一个仓库. 2、执行Git命令 1、进入到项目目录并且初始化git git init 2、添加目录下的文件到本地仓库 git add . 3、提交staged的文件...

_Change_
49分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部