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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/19687.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redux状态管理用法详解

在React中使用redux&#xff0c;官方要求安装俩个其他插件 - Redux Toolkit 和 react-redux 1.ReduxToolkit (RTK) 官方推荐编写 Redux 逻辑的方式&#xff0c;是一套工具的集合集&#xff0c;简化书写方式 简化 store 的配置方式&#xff1b; 内置 immer 支持…

dubbo复习:(19)dubbo 和spring整合(老古董)

一、服务端依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM…

华为SSH实验

华为SSH实验 实验拓扑&#xff1a; 实验要求&#xff1a;从SSH客户端AR1采用stelnet方式登录到SSH 服务器端。 实验步骤&#xff1a; 1.完成基本配置&#xff08;略&#xff09; sys Enter system view, return user view with CtrlZ. [AR1]sys CLIENT [CLIENT]INT g0/0/0 [C…

ECMAScript 详解:深入理解 JavaScript 的核心标准

ECMAScript 详解&#xff1a;深入理解 JavaScript 的核心标准 如果你是一名前端开发者&#xff0c;或者只是对编程感兴趣&#xff0c;那么你一定听说过 ECMAScript。它是 JavaScript 的标准&#xff0c;是现代 web 开发的基础。那么&#xff0c;究竟什么是 ECMAScript&#xf…

打造你的首个QT 5计算器应用

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;QT 5的力量与我们的计算器 二、QT 5基础&#xff1a;理解UI设计与文件…

Java多线程(04)—— 保证线程安全的方法与线程安全的集合类

一、CAS 与原子类 1. CAS CAS&#xff08;compare and swap&#xff09;&#xff0c;是一条 cpu 指令&#xff0c;其含义为&#xff1a;CAS(M, A, B); M 表示内存&#xff0c;A 和 B 分别表示一个寄存器&#xff1b;如果 M 的值和 A 的值相同&#xff0c;则把 M 和 B 的值交…

数字IC基础:主要的FPGA厂商

相关阅读 数字IC基础https://blog.csdn.net/weixin_45791458/category_12365795.html?spm1001.2014.3001.5482 Xilinx&#xff08;现已被AMD收购&#xff09; Xilinx, 成立于1984年&#xff0c;是FPGA&#xff08;现场可编程门阵列&#xff09;技术的创始者和市场领导者。该公…

dmdts连接kingbase8报错

dmdts连接kingbase报错 环境介绍1 人大金仓jdbc配置2 dmdts 人大金仓jdbc默认配置3 dmdts 修改jdbc配置4 达梦产品学习使用列表 环境介绍 dts版本 使用dmdts连接kingbase金仓数据库报错 无效的URL 对比jdbc连接串,修改配置解决 1 人大金仓jdbc配置 配置URL模版信息等 类名…

民国漫画杂志《时代漫画》第36期.PDF

时代漫画36.PDF: https://url03.ctfile.com/f/1779803-1248636233-8a4a9d?p9586 (访问密码: 9586) 《时代漫画》的杂志在1934年诞生了&#xff0c;截止1937年6月战争来临被迫停刊共发行了39期。 ps: 资源来源网络!

【高校科研前沿】南大王栋、吴吉春教授团队在深度学习助力水库生态调度和优化管理方面取得新进展,成果以博士生邱如健为一作发表于水环境领域国际权威期刊

1.文章简介 论文名称&#xff1a;Integration of deep learning and improved multi-objective algorithm to optimize reservoir operation for balancing human and downstream ecological needs 第一作者及单位&#xff1a;邱如健&#xff08;博士生 南京大学&#xff09;…

Linux自动挂载服务autofs讲解

1.产生原因 2.配置文件讲解 总结&#xff1a;配置客户端&#xff0c;先构思好要挂载的目录如&#xff1a;/abc/cb 然后在autofs.master中编辑&#xff1a; /abc&#xff08;要挂载的主目录&#xff09; /etc/qwe&#xff08;在这个文件里去找要挂载的副目录&#xff0c;这个名…

MySQL基础索引知识【索引创建删除 | MyISAM InnoDB引擎原理认识】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;MySQL之旅_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 一&#xff0c;索引用…

8-异常与错误

8-异常与错误 1、简介2、异常处理2.1 抛出异常2.2 捕获异常2.3 匹配顺序 3、异常说明4、构造函数中的异常5、析构函数中的异常6、标准库异常 1、简介 在程序编码过程中难免会出现错误&#xff0c;主要有&#xff1a;语法错误、逻辑错误、功能错误等&#xff0c;当我们面对以上…

密闭空间作业应如何做好安全防护?

在现代工业与日常工作中&#xff0c;密闭空间作业已逐渐成为许多行业不可或缺的一部分。然而&#xff0c;这些看似寻常的空间却隐藏着诸多不为人知的风险。从窒息性气体到易燃易爆物质&#xff0c;从物理性危险到心理压力&#xff0c;每一项都足以威胁到作业人员的生命安全。因…

Llama模型家族之RLAIF 基于 AI 反馈的强化学习(六) RLAIF 代码实战

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…

字符串匹配算法(三)Trie树算法

文章目录 Trie树的简介Trie树定义Trie树的实现 代码实现 Trie树的简介 Trie树定义 Trid树&#xff0c;也叫”字典树“。它是一个树形结构。专门处理字符串匹配的数据结构&#xff0c;用来解决字符串集中快速查找某个字符串的问题。 Trie 树的本质&#xff0c;就是利用字符串之…

LeetCode503:下一个更大元素Ⅱ

题目描述 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数&#xff0c;这…

记录一次云服务器无法连接的排查过程

运行环境&#xff1a;阿里云服务器 故障外显原因&#xff1a;登录失败,操作系统禁用了密码登录方式 控制台监控数据显示云盘读写BPS拉满了 因为之前问过线上售后&#xff0c;让安装了atop监控&#xff0c;&#xff0c;所以先打开atop日志&#xff1a; atop -r /var/log/atop…

自动驾驶中的长尾问题

自动驾驶中的长尾问题 定义 长尾问题&#xff08;Long-Tail Problem&#xff09;是指在数据分布中&#xff0c;大部分的数据集中在少数类别上&#xff0c;而剩下的大多数类别却只有少量的数据。这种数据分布不平衡的现象在许多实际应用中广泛存在&#xff0c;特别是在自动驾驶…

音视频开发—H265相关概念和压缩原理详解(GOP、宏块、帧内压缩、帧间压缩)

文章目录 1.什么是GOP&#xff1f;1.1 GOP介绍1.2.GOP中I帧/B帧/P帧1.3.I帧和IDR的区别联系I帧&#xff08;Intra Frame&#xff09;IDR帧&#xff08;Instantaneous Decoding Refresh Frame&#xff09;区别总结 1.4 帧与分组的关系1.5 SPS与PPSSPS&#xff08;Sequence Param…