iOS 无限滚动屏、走马灯、弹幕效果实现

前言:我是一个很懒的人,所以除了写小说,几乎不写别的什么文章,最近赶上公司做些社区化的需求,有需要写一个滚动留言板,有些像弹幕,所以自己就封装了一个,觉得可能对大家有用,所以就发上来,大家有用到的,可以参考参考。

一、效果

一行无限滚动
两行无限滚动
多行无限滚动

二、方案和策略

1. 我们暂时定义每一个横向滑动的组件叫轨道,每一个轨道上有若干个text控件,任一控件都是从屏幕最后侧外开始进入屏幕并开始滚动,所以每个text控件的中心点从初始值运动到恰好滑出最左侧屏幕的时候,其中心点的位移就是整个屏幕的宽,如下图所示:

控件center.x位移是屏幕宽

2. 每一个控件从右侧屏幕外开始运动,其运动距离(movedLength)刚好等于自身宽度(width)的时候,说明控件刚好运动到其尾部与屏幕右边框对齐(有控件间距的时候,则是其运动距离刚好等于其自身宽度加控件距离),如下图所示:

alabel.movedLength = alabel.frame.size.width + self.controlSpace

3. 在1的场景下,某一个控件刚好移出屏幕,则发出通知,将当前控件从屏幕移除,然后发回上层业务缓存起来。

4.在2的场景下,某一个控件刚好完全进入屏幕,此时需要发通知,通知上层业务方加载进入下一个控件,此时如果业务方控件缓存池有多余控件,则优先从缓存池复用控件,如果没有,则创建一个新的控件。(此处类似UITableViewCell复用)

5. 由以上可知,每一个控件必须有两个属性,一是初始加载到屏幕上的centerX值,二是记录本控件位移量的movedLength值。

6. 轨道组件维护着一个时钟,可以是NSTimer,也可以是DisplyLink,这个时钟每次刷新,都将遍历当前轨道中所有text控件,修改其x值和movedLength值,然后判断其x值是否满足刚好滑出屏幕和刚好完全滑入屏幕的条件,符合的话,采取对应的3或者4的操作

7. 作为轨道的数据源,上层业务方会提供一个数据队列dataArray,你还要维护一个游标作为索引,index,每次内层轨道索要一次数据,你就返回一个数据,然后将index++,

   7.1 如果你的app需求不需要无限循环,则在获取下一条数据的时候判断,是否达到了外层dataArray的尾部,如果达到了则不再返回数据,你的轨道发现拿到了空数据,则暂停滚动。

   7.2 如果你的app需要无限循环滚动,则在获取下一条数据的时候判断,是否达到了外层dataArray的尾部,达到了尾部,则将index重新归零,指向头部。

8. 特殊情况:有这样一种情况,比如dataArray数据过少,比如只有一条两条短的,一屏就能展示完,你还需要判断,当需要拉取下一条数据时,如果下一条数据与当前轨道中其它数据一样,则不拉取;然后你需要在轨道中额外添加一条判断:当text控件尾部抵达屏幕左侧边框时,判断如果后面没有别的控件,则从缓存池继续循环拉取。(判断的方法很简单,当前轨道中的控件就像UITableView的visibleCells,当前控件是最后一个控件的话,就表面后面没有别的控件)


三、上代码

1. 如果你们需求很简单,只需要一个text控件,就可以只定制一个我们自己的text控件,这个控件多了两个属性,如下:

2. 如果你的需求复杂,需要定制单独的文本View,如本文开头所示,可以定制一个自己的baseView,如下:

其数据类如下:

3. 务必注意:为了避免意外卡顿,需要将每一个text控件的frame和数据都准备好,放在数据类中,这样你的轨道控件可以只做渲染和时钟操作,避免大量计算造成卡顿或者遗漏数据

4. 核心控件,单轨道

5. 单轨道BDSKAutoRunView的.m文件如下:

    5.1 首先添加一个分类,将时钟以及放置滚动内容视图生命一下,还有一个线程访问的简单锁

  5.2 然后初始化一些必要数据,这里文本控件的横向间距默认为20,滚动速度1,

5.3 添加将外层传入的view加载到当前轨道的方法,默认将之放在轨道末尾,再给它加上底层txt控件点击事件的传递,最后开启时钟

 5.4 时钟与时钟方法概览,其中start,pause,stop是供外部调用,beginTimer与stopTimer等供内部调用

 5.5 具体的timer方法

5.6 核心方法,时钟刷新动作


   5.7 最后是点击动作和获取下一条通知

    5.8 到此处为止,单轨道定制完成,开始定制多轨道

6. 滚动屏控件头文件

7. 滚动屏BDSKSSRollView.m文件,添加一个锁

8. 定制初始化方法和rollPathCount的setter方法,创建相应数量的轨道

8.1 实现轨道的delegate,为止提供数据和获取事件通知,这里缓存对象,简单使用对象的内存地址作为key,你也可以用其他哈希值

8.2 外部数据池游标需要加判断,不能越界,将要越界时,返回头部,继续返回数据

8.3 复用返回数据核心函数,每次先取缓存的text控件,有则利用新数据刷新控件,没有缓存text控件,则创建新的,最后的startCenter与位移信息重新设置。

9.综合以上,就是滚动屏所有相关代码,使用的时候怎么使用呢?

初始化一个滚动屏的view,然后添加到你想要添加的视图上就可以了,其中titleArray就是你从服务端获取到的数据源。这里有个要注意的策略:什么时候去再次拉取服务端数据。

有两种方案,1.第一次拉取到数据后,先让屏幕滚动着,然后在后台静默继续请求数据,然后塞进titleArray中就可以了 2. 第一次拉取到数据后,让滚动屏先滚动,然后在游标index++到倒数第N个时,发通知,由外部发请求从服务端拉取新数据

10. 由于复用机制的存在,使得屏幕上的控件始终不会累积增加,所以内存消耗并不大,而如果不服用,直接从屏幕上remove然后由系统抛弃,每次都重新创建新的text控件也没问题,只是每次都要创建一个新的控件,简单控件还好,复杂控件就损耗性能了。


总结:以上就是全部的滚动屏和走马灯定制的全部内容,只是自己花两天简单做的实现,找时间我会把demo放出来,有需要的朋友可以下载,当然,如果有什么疑问,欢迎留言和咨询,不过我比较懒,不一定每天登陆上来简书,所以不一定能及时回复,还请海涵。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容