当前位置: 首页 > news >正文

RxSwift - 实现一个MVVM架构的TableView

文章目录

  • RxSwift - 实现一个MVVM架构的TableView
    • 前沿
    • MVVM架构的Tableview
      • 目录结构
      • 1、模型(Model)
      • 2、视图模型(ViewModel)
      • 3、视图(View)
    • 界面效果

RxSwift - 实现一个MVVM架构的TableView

前沿

MVVM架构在在实际开发中被广泛应用,它让代码结构清晰美观,易于阅读维护,同时也弥补了MVC结构中Controller臃肿的问题

今天来实现一个基于RxSwift的基础TableView页面

效果:使用RxSwift,将ViewModel进行绑定,实现动态修改数据时更新UI

MVVM架构的Tableview

目录结构

以下是目录结构

-w400

目录由ViewModelViewModel三个文件夹组成

1、模型(Model)

Model文件夹下新建Product文件

import Foundationstruct Product {let imgName: String // 图let name: String// 名称let price: String// 价格
}

模型简单表示了一个商品的

2、视图模型(ViewModel)

ViewModel文件夹下新建ProductViewModel文件。它相当于是ViewModel的桥梁,在ViewModel中会有相应的获取数据以及处理数据的方法,然后将数据传输到View

import Foundation
import RxSwiftclass ProductViewModel {// PublishSubject: 只会发送新的事件给订阅者,订阅之前的事件不会发送// BehaviorSubject: 会保持最新的值,并将其发送给新的订阅者let items = PublishSubject<[Product]>()
//  let items = BehaviorSubject<[Product]>(value: [])var productArray: [Product]!func fetchProductList() {// 在这里可以做网络请求// 咱们就直接用假数据productArray = [Product(imgName: "apple", name: "apple", price: "10"),Product(imgName: "banana", name: "banana", price: "5"),Product(imgName: "pear", name: "pear", price: "4"),Product(imgName: "watermelon", name: "watermelon", price: "3"),Product(imgName: "mango", name: "mango", price: "8")]items.onNext(productArray)
//        items.onCompleted()}func addData() {productArray.append(Product(imgName: "peach", name: "peach", price: "7"))items.onNext(productArray)}
}

该类中:

  • 定义了时间发布者items,使用PublishSubject类型
  • 定义获取数据的方法fetchProductList(),获取完数据后,使用onNext将事件发布出去。代码中注释掉onCompleted(),是因为想要实现后续数据更新的操作,onCompleted会终止序列,使其不再接收新的元素。
  • 定义addData()方法,界面中将通过点击按钮模拟增加数据操作

3、视图(View)

View层,首先有个简单的CellProductTableViewCell,它有一个数据有属性item,赋值时进行UI内容样式设置

import UIKitclass ProductTableViewCell: UITableViewCell {var item: Product? = nil {didSet{textLabel?.text = item?.name}}override func awakeFromNib() {super.awakeFromNib()// Initialization code}override func setSelected(_ selected: Bool, animated: Bool) {super.setSelected(selected, animated: animated)// Configure the view for the selected state}}

接下来是ViewController

import UIKit
import RxSwift
import RxCocoaclass ViewController: UIViewController, UIScrollViewDelegate {private let bag = DisposeBag()private let viewModel = ProductViewModel()lazy var tableView: UITableView = {let tableView = UITableView(frame: view.bounds, style: UITableView.Style.grouped)view.addSubview(tableView)return tableView}()override func viewDidLoad() {super.viewDidLoad()tableView.rx.setDelegate(self).disposed(by: bag)bindTableView()let btn:UIButton = UIButton(type: .system)btn.frame = CGRectMake(10, view.frame.size.height - 80, view.frame.size.width - 20, 50)btn.backgroundColor = .lightGraybtn.setTitle("addData", for: UIControl.State.normal)btn.rx.tap.subscribe(onNext: { [unowned self] inself.viewModel.addData()}).disposed(by: bag)view.addSubview(btn)}private func bindTableView() {tableView.register(ProductTableViewCell.self, forCellReuseIdentifier: "cellId")viewModel.items.bind(to: tableView.rx.items(cellIdentifier: "cellId", cellType: ProductTableViewCell.self)) { (row,item,cell) incell.item = item}.disposed(by: bag)tableView.rx.modelSelected(Product.self).subscribe(onNext: { item inprint("SelectedItem: \(item.name)")}).disposed(by: bag)viewModel.fetchProductList()}
}
  • 定义private let bag = DisposeBag(),作用就是在合适的时机自动调用这些 Disposable 对象的 dispose() 方法,释放资源,避免内存泄漏
  • 持有ViewModelprivate let viewModel = ProductViewModel()
  • 初始化tableView
  • viewDidLoad()中,指定了tableView代理为self,然后将viewModelitems事件绑定到tableView,即将数据源绑定到表视图行。同时订阅了选中某个模型的事件modelSelected,即选中某个Cell的事件。(使用RxCocoa提供的方法实现)
  • 增加一个按钮,点击时调用viewModel.addData()方法,动态修改数据源。因为已将tableView绑定到数据源,视图也将动态刷新

界面效果

-w200

@oubijiexi

相关文章:

RxSwift - 实现一个MVVM架构的TableView

文章目录 RxSwift - 实现一个MVVM架构的TableView前沿MVVM架构的Tableview目录结构1、模型&#xff08;Model&#xff09;2、视图模型&#xff08;ViewModel&#xff09;3、视图&#xff08;View&#xff09; 界面效果 RxSwift - 实现一个MVVM架构的TableView 前沿 MVVM架构在…...

在 CentOS 7 上安装并配置 Redis 允许远程连接的详细教程

第一部分&#xff1a;安装 Redis Redis 是一款高性能的键值存储系统&#xff0c;广泛应用于缓存、消息队列及数据库场景。下面是如何在 CentOS 7 系统上安装 Redis 的步骤。 步骤1&#xff1a;安装 EPEL 仓库 EPEL (Extra Packages for Enterprise Linux) 提供了许多 CentOS 默…...

越来越多企业选择开源批发订货系统

在当今竞争激烈的市场环境中&#xff0c;越来越多的企业选择开源批发订货系统来提高运营效率、降低成本并实现业务的数字化转型。以下是开源批发订货系统的四大优势及其重要功能&#xff1a; 首先&#xff0c;开源批发订货系统具有高度的灵活性和定制性。由于其源代码开放&…...

KT6368A双模蓝牙芯片上电到正常发送AT指令或指令复位需要多久

一、简介 KT6368A芯片上电到正常发送AT指令&#xff0c;或者开启蓝牙广播被搜索到&#xff0c;或者指令复位需要多久等等系列问题总结 详细描述 其实这些问题归结到一起&#xff0c;就还是一个问题&#xff0c;芯片上电需要多久的时间 在另外一份文档里面&#xff0c;是有描…...

代码随想录算法训练营第38天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

代码随想录算法训练营第38天 | 509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯 理论基础自己看到题目的第一想法看完代码随想录之后的想法 链接: 509. 斐波那契数 链接: 70. 爬楼梯 链接: 746. 使用最小花费爬楼梯 理论基础 五部曲&#xff1a; 1.确定dp数组&#xf…...

变现实谈,我要的不是灵光一现,而是真实的实现!——感悟篇

变现要的是行动不是想法 正文时代奇点奇迹 点题以己及人 正文 每当我看到了一个有趣的事情 我会在脑中构思一些想法 会贴合我当下的想要做的事情 比如 在我写下这篇文章之前 我看到了 二战期间的诞生的一个奇迹 可口可乐 我就思考 咦 原来可口可乐居然是在这么个时间点成长…...

Matlab操作Excel筛选指定数据的对应数据

Matlab中在表格中寻找指定汉字&#xff0c;并返回其所在行数&#xff0c; 将该行数的另一列提取出来。 目录 一、前言 二、直接在命令行输出 三、保存筛选数据excel 一、前言 源数据excel&#xff1a; 指定汉子&#xff1a;买&#xff0c;得到下面数据&#xff1a; 二、直接…...

对于C++STL及其时间复杂度的总结

由于本次在山东CCPC邀请赛中&#xff0c;对于堆的时间复杂度记忆不清晰&#xff0c;导致第4题没有做出来&#xff0c;与铜牌失之交臂&#xff0c;故觉应整理STL的时间复杂度。 本文仅整理有用&#xff08;竞赛&#xff09;的stl及其用法&#xff0c;并且不阐述过于基础的内容。…...

Docker搭建FRP内网穿透服务器

使用Docker搭建一个frp内网穿透 在现代网络环境中&#xff0c;由于防火墙和NAT等原因&#xff0c;内网设备无法直接被外网访问。FRP (Fast Reverse Proxy) 是一款非常流行的内网穿透工具&#xff0c;它能够帮助我们将内网服务暴露给外网。本文将介绍如何在Linux服务器上使用Do…...

【NumPy】掌握NumPy的divide函数:执行高效的数组除法操作

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…...

您的虚拟机未能继续运行,原因是遇到一个可纠正的错误。请保留挂起状态并纠正错误,或放弃挂起状态。

镜像&#xff1a;应急响应靶机 错误信息 此虚拟机的处理器所支持的功能不同于保存虑拟机状态的虚拟机的处理器所支持的功能。 从文件"E:\XXX.vmss"还原 CPU 状态时出错。 您的虚拟机未能继续运行&#xff0c;原因是遇到一个可纠正的错误。请保留挂起状态并纠正错误…...

FPGA DMA IP核使用指南

摘要 本文旨在介绍FPGA中DMA(Direct Memory Access)IP核的使用,包括其基本框架、测试代码编写以及仿真波形的分析。DMA是一种允许外围设备直接与内存进行数据交换的技术,无需CPU的介入,从而提高了数据传输的效率。 1. 引言 在现代FPGA设计中,DMA IP核因其…...

【博客20】缤果Matlab串口调试助手V1.0(中级篇)

超级好用的Matlab串口调试助手 开发工具: MATLAB 2024a中文版 (编程语言matlab) -> Matlab APP Designer 目录 前言 一、软件概要&#xff1a; 二、软件界面&#xff1a; 1.App演示 ​ ​---- ◇♣♡♠ ---- 2.其他扩展App展示 ​编辑 三、获取 >> 源码以及G…...

南京威雅学校:2024年度大戏《Tinkerbell(小叮当)》震撼落幕

三天连演三场 两小时十六幕高潮迭起的舞台故事 一百五十余名师生台前幕后全统筹 逾千名观众现场观演 四个城市五大平台同步直播 南京威雅2024年度大戏 《Tinkerbell&#xff08;小叮当&#xff09;》震撼落幕 它以商演级别的舞台设计 宏大而精密的舞台调度 直击心灵的…...

Kotlin 函数

文章目录 函数的定义函数的返回值参数默认值 & 调用时参数指定函数作用域Lambda 表达式匿名函数内联函数扩展函数中缀函数递归函数 & 尾递归函数 函数的定义 函数可以理解成一个小小的加工厂&#xff0c;给入特定的原材料&#xff0c;它就会给出特定的产品。 fun [接…...

动态路由协议实验——RIP

动态路由协议实验——RIP 什么是RIP ​ RIP(Routing Information Protocol,路由信息协议&#xff09;是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;是一种动态路由选择协议&#xff0c;用于自治系统&#xff08;AS&#xff09;内的路由信息的传递。RIP协议基于…...

数据结构 | 二叉树(基本概念、性质、遍历、C代码实现)

1.树的基本概念 树是一种 非线性 的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。 把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&#xff0c;称为根…...

很多Oracle中的SQL语句在EF中写不出来

很多复杂的Oracle SQL语句在Entity Framework&#xff08;EF&#xff09;中很难直接表达出来。虽然EF提供了一种方便的方式来使用C#代码查询和操作数据库&#xff0c;但它在处理某些复杂的SQL特性和优化时可能会有局限性。 以下是一些在EF中可能难以直接实现的Oracle SQL功能和…...

浏览器打开PHP文件弹出下载而不是运行代码

说明 使用phpstudy&#xff0c;极少会出现这种情况。 这里主要是帮助大家理解&#xff0c;为什么上传的木马不运行。 问题原因 首先需要理解&#xff0c;访问PHP文件弹出下载&#xff0c;说明服务端的容器&#xff08;比如Apache或者Nginx&#xff09;把文件当成了一个普通二…...

安卓自定义UI组件开发流程

安卓自定义ui组件开发流程 开发安卓自定义UI组件的流程大致可以分为以下几个步骤&#xff1a; 确定需求和设计&#xff1a; 确定需要自定义的UI组件的功能和外观。设计组件的交互逻辑和视觉效果。 创建自定义组件类&#xff1a; 创建一个新的Java类&#xff0c;继承自View、V…...

自托管代码仓库聚合分析平台CodeStacker:架构设计与部署指南

1. 项目概述&#xff1a;一个为开发者打造的代码仓库聚合与智能分析工具如果你和我一样&#xff0c;每天需要面对GitHub、GitLab、Bitbucket等不同平台上的几十个甚至上百个代码仓库&#xff0c;那么“仓库管理”这件事本身&#xff0c;可能就已经消耗了你大量的精力。哪个项目…...

6SE7015-0EP50-Z 控制逆变器单元

6SE7015-0EP50-Z 是西门子 SIMOVERT MasterDrives 系列的一款控制逆变器单元&#xff0c;结构紧凑、可靠性高&#xff0c;适用于工业环境中的电机调速控制。中间 15 条特点&#xff1a;结构紧凑&#xff0c;占用空间小。支持三相 380V 至 480V 宽电压输入。输出频率范围宽&…...

Midscene.js如何实现跨平台AI自动化测试:从零到精通的5步配置指南

Midscene.js如何实现跨平台AI自动化测试&#xff1a;从零到精通的5步配置指南 【免费下载链接】midscene AI-powered, vision-driven UI automation for every platform. 项目地址: https://gitcode.com/GitHub_Trending/mid/midscene Midscene.js是一款基于视觉语言模型…...

2230固态硬盘延长安装技巧指南!

2230规格的M.2固态硬盘因体积小巧&#xff0c;广泛应用于掌机、轻薄笔记本和微型PC&#xff0c;但许多主板的M.2插槽默认为2280规格&#xff0c;导致2230硬盘“装不稳”。本文详细讲解2230与2280的尺寸差异、延长安装的核心方法&#xff08;转接支架、螺丝柱调整、散热适配&…...

基于MCP协议构建Next.js项目智能中枢:自动化AI开发助手集成

1. 项目概述&#xff1a;一个为Next.js Prisma项目注入“项目智能”的MCP服务器如果你和我一样&#xff0c;日常开发重度依赖像Claude Code、Cursor这类AI编程助手&#xff0c;那你肯定遇到过这样的痛点&#xff1a;每次打开一个新项目&#xff0c;或者切换到一个复杂的模块&a…...

从冷冰冰播报到“会呼吸的语音”:ElevenLabs非正式情绪语音落地4大行业案例(客服话术/有声书/AI陪伴/短视频配音),含真实AB测试CTR提升27%数据

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;从冷冰冰播报到“会呼吸的语音”&#xff1a;ElevenLabs非正式情绪语音的技术跃迁 传统TTS系统常陷入语调扁平、节奏机械、情感缺失的困境——即便输入“我太开心了&#xff01;”&#xff0c;输出也如…...

Sass迁移实战:告别node-sass,拥抱现代前端工具链

1. 为什么前端开发者都在抛弃node-sass&#xff1f; 最近两年&#xff0c;但凡你打开一个前端项目的package.json&#xff0c;十有八九会发现依赖项里已经找不到node-sass的身影了。这不是巧合&#xff0c;而是整个前端生态的一次集体升级。作为一个经历过多次技术栈迁移的老前…...

关键基础设施网络安全防御指南:从漏洞扫描到实战加固

1. 项目概述&#xff1a;一场迫在眉睫的网络空间风暴最近&#xff0c;如果你关注网络安全动态&#xff0c;会发现一种前所未有的紧迫感正在美国的关键基础设施领域蔓延。这种感觉&#xff0c;就像暴风雨来临前&#xff0c;气压骤降带来的那种沉闷与不安。作为一名在工业控制系统…...

Soot印相不是风格,是光学物理过程!20年暗房工程师拆解Midjourney如何模拟FeSO₄还原反应与纸基纤维吸附曲线

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Soot印相不是风格&#xff0c;是光学物理过程&#xff01; Soot印相&#xff08;Soot Photogram&#xff09;是一种基于真实碳黑微粒沉积与光敏材料相互作用的直摄成像技术&#xff0c;其本质并非后期滤…...

一天一个开源项目(第100篇):Easy-Vibe - Datawhale 出品的 AI 时代编程入门教程

引言 “会说话&#xff0c;就能做应用。” 这是"一天一个开源项目"系列的第100篇文章——一个小小的里程碑。 选择 Easy-Vibe 作为第100篇&#xff0c;有一种奇妙的对称感。这个系列从第一篇开始&#xff0c;记录的都是"工具"——各种帮助开发者做事更快、…...