iOS 自动翻滚广告条(榜单条)实现方案
引言
在直播场景中,榜单信息、活动公告或者广告推广通常需要以醒目的方式展示,但由于屏幕空间有限,一次只能显示一条内容。为了让用户能够持续关注这些信息,我们可以实现一个自动翻滚的广告条(或榜单条),让内容定期滚动更新,类似于上下轮播的效果。
本篇博客将介绍如何使用 UITableView + Timer 来实现这一功能,使其能够自动滚动、循环播放,并且在数据更新时依然保持流畅的用户体验。
代码实现
我们以直播间的小时榜信息条为例。由于该场景下的数据更新频率较低,并且滚动不需要过快,而是以固定速度自动翻滚,因此采用UITableView + Timer的方案即可满足需求。
在定时器的选择上,我们使用了Repeat,相比于手动管理Timer的启动和销毁,这种方式更加简洁高效,能够稳定地控制翻滚节奏。
基本UI结构
翻滚条的全部UI就是一个UITableView,但记得设置它不可交互放置用户手动滚动。
class MWVerticalAutoRollView: UIView,UITableViewDelegate,UITableViewDataSource {/// 滚动列表视图private let tableView = UITableView(frame: .zero,style: .plain)....override init(frame: CGRect) {super.init(frame: frame)addTableView()}required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}// 添加列表private func addTableView() {self.addSubview(tableView)tableView.snp.makeConstraints { (make) inmake.edges.equalToSuperview()}tableView.backgroundColor = .cleartableView.isPagingEnabled = truetableView.isScrollEnabled = falsetableView.delegate = selftableView.dataSource = selftableView.separatorStyle = .nonetableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")}/// 注册cell 泛型/// - Parameterfunc registerCell<T:UITableViewCell>(cell:T.Type) {tableView.register(cell, forCellReuseIdentifier: NSStringFromClass(cell))}
- 创建UITableView的实例,当做上下翻滚的列表。
- 设置UITableView的布局,分页,以及禁止滑动事件。
- 此外创建了一个对外暴漏的方法用来注册自定义UITableViewCell。
数据处理
想要实现无限的翻滚,以及针对只有一条数据的情况我们首先需要给数据进行处理,主要将第一个数据再次添加到最后一个数据,和轮播一样,以实现假的无限翻滚。
/// 数据模型数组private var dataList:[Any] = []
/// 设置数据/// - Parameter dataList: 数据func setData(dataList:[Any]) {var results:[Any] = []if dataList.count == 0 {return}if dataList.count == 1 {results.append(dataList.first!)results.append(dataList.first!)results.append(dataList.first!)}if dataList.count == 2 {results.append(dataList.first!)results.append(dataList.last!)results.append(dataList.first!)}if dataList.count >= 3 {results = dataListresults.append(dataList.first!)}self.dataList = resultstableView.reloadData()startTimer()}
在UITableView的代理方法中,显示dataList数据。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {return dataList.count}func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {if let delegate = delegate {let data = dataList[indexPath.row]return delegate.mwVerticalAutoRollView(self, cellForRowAt: indexPath, data: data)}MWAssert(false, "MWVerticalAutoRollView delegate is nil!")return tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)}func dequeueReusableCell<T:UITableViewCell>(cell:T.Type,indexPath:IndexPath) -> T {return tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(cell), for: indexPath) as! T}func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {return 24.0}
- 数据的数量直接使用dataList.count放回。
- UITableView的cell,我们通过代理向该组件内部传递,这样我们可以自定义任何样式的滚动item。
- 固定列表高度为24。
实现定时滚动
使用Repeater每2.5秒执行一次,每次切换到下一个row,当切换到最后一个时,隐藏动画直接切换到第一个以实现无线翻滚。
private func startTimer() {self.timer = Repeater.every(.seconds(2.5)) { [weak self] _ inguard let self = self else { return }DispatchQueue.main.async {self.autoScroll()}}}@objc func autoScroll() {currentIndex += 1if currentIndex >= dataList.count {currentIndex = 0// 无动画跳回开头CATransaction.begin()CATransaction.setDisableActions(true)tableView.scrollToRow(at: IndexPath(row: currentIndex, section: 0), at: .top, animated: false)CATransaction.commit()} else {// 平滑滚动到下一行tableView.scrollToRow(at: IndexPath(row: currentIndex, section: 0), at: .top, animated: true)}}
- 开始定时器,主线程执行滚动方法。
- 每次执行autoScroll()方法,currentIndex+1,滚动到下一行。
- 如果已经是最后一行,将currentIndex设置为0,隐藏隐式动画,无动画切换到第一行。
使用示例
组件使用起来非常简单,在需要使用的地方直接创建广播滚动组件MWVerticalAutoRollView的实例,并设置对应布局和数据。
/// 滚动榜单视图private let rollHotListView = MWVerticalAutoRollView()/// 榜单数据列表private var rollHotListDataList = [String]()
/// 添加滚动榜单视图private func addRollHotListView() {guard let containerView = self.horSliderContentView else {return}containerView.addSubview(rollHotListView)rollHotListView.isHidden = truerollHotListView.delegate = selfrollHotListView.snp.makeConstraints { (make) inmake.leading.equalToSuperview().offset(16.0)make.top.equalToSuperview().offset(MW_TOP_SAFE_HEIGHT + 72)make.height.equalTo(24.0)make.trailing.equalToSuperview().offset(-16.0)}rollHotListView.registerCell(cell: MWRollHotListCell.self)}
rollHotListView.setData(dataList: dataList)
实现代理方法,在代理方法中为自定义的WMRollHotListcell渲染数据。
func mwVerticalAutoRollView(_ view: MWVerticalAutoRollView, cellForRowAt indexPath: IndexPath,data:Any) -> UITableViewCell {let cell = view.dequeueReusableCell(cell: MWRollHotListCell.self, indexPath: indexPath)if let content = data as? MWRollHotListModel {cell.rollHotListModel = content}cell.selectionStyle = .nonecell.backgroundColor = .clearcell.contentView.backgroundColor = .clearreturn cell}
结语
通过使用 UITableView + Timer
实现自动翻滚的广告条或榜单条,我们能够在直播间等场景中,简便且高效地展示动态信息。这个方案既满足了平滑滚动的需求,又避免了频繁的数据更新带来的性能问题。同时,通过简单的定时器控制,我们能够灵活地调整滚动的速度和频率,保证了良好的用户体验。
相关文章:

iOS 自动翻滚广告条(榜单条)实现方案
引言 在直播场景中,榜单信息、活动公告或者广告推广通常需要以醒目的方式展示,但由于屏幕空间有限,一次只能显示一条内容。为了让用户能够持续关注这些信息,我们可以实现一个自动翻滚的广告条(或榜单条)&a…...

TensorFlow深度学习实战(7)——分类任务详解
TensorFlow深度学习实战(7)——分类任务详解 0. 前言1. 分类任务1.1 分类任务简介1.2 分类与回归的区别 2. 逻辑回归3. 使用 TensorFlow 实现逻辑回归小结系列链接 0. 前言 分类任务 (Classification Task) 是机器学习中的一种监督学习问题,…...

动态规划问题——青蛙跳台阶案例分析
问题描述: 一只青蛙要跳上n级台阶,它每次可以跳 1级或者2级。问:青蛙有多少种不同的跳法可以跳完这些台阶? 举个例子: 假设台阶数 n 3 ,我们来看看青蛙有多少种跳法。 可能的跳法: 1. 跳1级…...
element-ui使用el-table,保留字段前的空白
项目名称项目编号1、XXXXX1111111111111111111 1.1 XXXXX11111111111111222222222 如上表格中,实现项目名称字段1.1前空白的效果。 从JAVA返回的数据带有空白,即数据库中插入的数据带有空白。 原先写法: <el-table><el-tabl…...
kamailio中路由模块汇总
功能模块描述请求路由 (request_route)主要处理进入的SIP请求,包含初步检查、NAT检测、CANCEL请求处理、重传处理等。处理通过REQINIT、NATDETECT、RELAY等子模块的调用。CANCEL处理对CANCEL请求进行处理,包括更新对话状态并检查事务。如果事务检查通过&…...
如何使用 DeepSeek 搭建本地知识库
使用 DeepSeek 搭建本地知识库可以帮助您高效管理和检索本地文档、数据或知识资源。以下是详细的步骤指南: 1. 准备工作 (1) 安装 DeepSeek 确保您的系统已安装 Python 3.8 或更高版本。使用 pip 安装 DeepSeek: bash pip install deepseek (2) 准备…...
网络HTTP详细讲解
学习目标 什么是HTTPHTTP的请求和响应常见的HTTP状态码HTTP的安全性 什么是HTTP?HTTP的请求和响应,常见的HTTP状态码,HTTP的安全性 什么是HTTP HTTP(HyperText Transfer Protocol,超文本传输协议)是一种用…...

《Origin画百图》之边际分布曲线图
《Origin画百图》第六集——边际分布曲线图 入门操作可看《30秒,带你入门Origin》 边际分布曲线图,其中包含散点图形,而在图的边际有着分布曲线图。在比较数据以查看多个变量之间是否存在关系时非常有用。 1.数据准备:为多列XY数…...
【Milvus】向量数据库pymilvus使用教程
以下是根据 Milvus 官方文档整理的详细 PyMilvus 使用教程,基于 Milvus 2.5.x 版本: PyMilvus 使用教程 目录 安装与环境准备连接 Milvus 服务数据模型基础概念创建集合(Collection)插入数据创建索引向量搜索删除操作完整示例注…...
React 生命周期函数详解
React 组件在其生命周期中有多个阶段,每个阶段都有特定的生命周期函数(Lifecycle Methods)。这些函数允许你在组件的不同阶段执行特定的操作。以下是 React 组件生命周期的主要阶段及其对应的生命周期函数,并结合了 React 16.3 的…...

第 26 场 蓝桥入门赛
2.对联【算法赛】 - 蓝桥云课 问题描述 大年三十,小蓝和爷爷一起贴对联。爷爷拿出了两副对联,每副对联都由 N 个“福”字组成,每个“福”字要么是正的(用 1 表示),要么是倒的(用 0 表示&#…...
组合(力扣77)
从这道题开始,我们正式进入回溯算法的学习。之前在二叉树中只是接触到了一丢丢,而这里我们将使用回溯算法解决很多经典问题。 那么这道题是如何使用回溯算法的呢?在讲回溯之前,先说明一下此题是如何递归的。毕竟回溯递归不分家&a…...

网络工程师 (22)网络协议
前言 网络协议是计算机网络中进行数据交换而建立的规则、标准或约定的集合,它规定了通信时信息必须采用的格式和这些格式的意义。 一、基本要素 语法:规定信息格式,包括数据及控制信息的格式、编码及信号电平等。这是协议的基础,确…...

Linux之文件IO前世今生
在 Linux之文件系统前世今生(一) VFS中,我们提到了文件的读写,并给出了简要的读写示意图,本文将分析文件I/O的细节。 一、Buffered I/O(缓存I/O)& Directed I/O(直接I/O&#…...

如何在Windows中配置MySQL?
MySQL是一个广泛使用的开源关系型数据库管理系统,它支持多种操作系统平台,其中包括Windows。无论是开发者进行本地开发,还是管理员为应用程序配置数据库,MySQL都是一个非常流行的选择。本篇文章将详细介绍如何在Windows操作系统中…...

Kafka 入门与实战
一、Kafka 基础 1.1 创建topic kafka-topics.bat --bootstrap-server localhost:9092 --topic test --create 1.2 查看消费者偏移量位置 kafka-consumer-groups.bat --bootstrap-server localhost:9092 --describe --group test 1.3 消息的生产与发送 #生产者 kafka-cons…...
数学知识学习1
1、数论 1质数判定 i<n/i优化O(sqrt(n)) bool is_prime(int n){if(n<2)return false;for(int i2;i<n/i;i){if(n%i0)return false;} true; } 分解质因数 i<n/i优化O(sqrt(n)) // 定义一个函数 divide,接收一个整数 n 作为参数,用于分解质…...
【AI日记】25.02.08
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】【读书与思考】【AI应用】 探索 AI 应用探索周二有个面试,明后天打算好好准备一下,我打算主要研究下 AI 如何在该行业赋能和应用,以及该行业未来的发展前景和公司痛点&#…...

Lecture8 | LPV VXGI SSAO SSDO
Review: Lecture 7 | Lecture 8 LPV (Light Propagation Volumes) Light Propagation Volumes(LPV)-孤岛惊魂CryEngine引进的技术 LPV做GI快|好 大体步骤: Step1.Generation of Radiance Point Set Scene Representation 生成辐射点集的场景表示:辐射…...
Java中实现定时锁屏的功能(可以指定时间执行)
Java中实现定时锁屏的功能(可以指定时间执行) 要在Java中实现定时锁屏的功能,可以使用java.util.Timer或java.util.concurrent.ScheduledExecutorService来调度任务,并通过调用操作系统的命令来执行锁屏。下面我将给出一个基本的…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...