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 Foundation

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

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

2、视图模型(ViewModel)

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

import Foundation
import RxSwift

class 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 UIKit

class 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 RxCocoa

class 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 = .lightGray
        btn.setTitle("addData", for: UIControl.State.normal)
        btn.rx.tap
            .subscribe(onNext: { [unowned self] in
            self.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) in
            cell.item = item
        }.disposed(by: bag)
        
        tableView.rx.modelSelected(Product.self).subscribe(onNext: { item in
            print("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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IBM开源Granite Code模型,多尺寸可选,支持多种代码任务,性能媲美 CodeLlama

前言 近年来&#xff0c;大型语言模型&#xff08;LLM&#xff09;在代码领域展现出惊人的潜力&#xff0c;为软件开发流程带来了革命性的改变。代码 LLM 不仅能够生成高质量代码&#xff0c;还能帮助程序员修复错误、解释代码、编写文档等等&#xff0c;极大地提高了软件开发…

MyBatis通用Mapper:简化数据库操作的利器

引言 在软件开发中&#xff0c;数据库操作是不可或缺的一部分。通常我们会使用mybatis&#xff0c;的MBG插件&#xff0c;自动生成表对应的基本操作语句xml。 当我们的表字段发生变化的时候&#xff0c;我们需要修改实体类和Mapper文件定义的字段和方法。如果是增量维护&…

为何ICLR未能进入CCF推荐期刊会议列表?

会议之眼 快讯 最近小编在思考一个问题&#xff1a;ICLR&#xff08;International Conference on Learning Representations&#xff09;即国际学习表征会议自2013年诞生以来&#xff0c;ICLR以其开放的学术氛围、创新的研究议题和前沿的科学探索&#xff0c;迅速成为AI领域不…

【工具】 MyBatis Plus的SQL拦截器自动翻译替换“?“符号为真实数值

【工具】 MyBatis Plus的SQL拦截器自动翻译替换"?"符号为真实数值 使用MyBatis的配置如下所示&#xff1a; mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl调用接口&#xff0c;sql日志打印如下&#xff1a; 参数和sql语句不…

苏州金龙新V系客车科技助力“粤”动广州

粤动活力新V系&#xff01; 5月23日&#xff0c;苏州金龙新V系智慧客车推介会在羊城广州举行。活动现场展出了4款新V系代表车型&#xff0c;来自广东省旅游客运、道路运输行业的200余位从业者齐聚一堂&#xff0c;共同品鉴、体验了苏州金龙新V系产品的“新、心、芯”魅力。苏州…

Perplexity 搜索引擎刚刚推出了新的页面功能——维基百科可以扔了

Perplexity 允许用户根据搜索结果创建自定义页面 人工智能搜索引擎初创公司 Perplexity 推出了一项新功能&#xff0c;使其结果更具粘性&#xff0c;允许用户将研究转变为易于共享的页面。页面建立在 Perplexity 中现有的人工智能驱动的搜索功能之上&#xff0c;该功能使用与 …

Artifactory清理二进制文件丢失的制品

一、摘要 当制品上传到 Artifactory 时&#xff0c;Artifactory 会在数据库中记录制品的相关元数据信息&#xff0c;包括文件路径、大小、校验和&#xff08;如 MD5、SHA1&#xff09;、上传时间、索引、依赖等。实际的制品二进制文件会存储在指定的存储后端&#xff0c;具体的…

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

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

2年go蓝炎科技、爱诗科技面试经历,期望薪资22K

广州蓝炎科技一面 1、简单自我介绍&#xff1f;用的什么技术栈&#xff1f; 2、go的map是线程安全的吗&#xff1f; 3、Channel一般会在什么场景下使用&#xff1f;往一个未初始化的channel发送数据&#xff0c;会怎样&#xff1f; 4、关于go里头的随机数是线程安全的吗&am…

不同厂商SOC芯片在视频记录仪领域的应用

不同SoC公司芯片在不同产品上的应用信息&#xff1a; 大唐半导体 芯片型号: LC1860C (主控) LC1160 (PMU)产品应用: 红米2A (399元)大疆晓Spark技术规格: 28nm工艺&#xff0c;4个ARM Cortex-A7处理器&#xff0c;1.5GHz主频&#xff0c;2核MaliT628 GPU&#xff0c;1300万像…

基于51单片机多功能防盗报警proteus仿真( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机多功能防盗报警系统 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单&&下载链接 基于51单片机多功能防盗报警系统( proteus仿真程序设计报告原理图讲解视频&#xff09; 仿真图proteus8.9及以上…

打开C语言常用的内存函数大门(二)—— memmove()函数 (内含memmove的讲解和模拟实现)

文章目录 1. 前言2. memmove()函数2.1 memmove()函数与memcpy()函数的差异2.2 memmove()函数的原型2.3 memmove()函数的使用案例 3. memmove()函数的模拟实现4. 总结 1. 前言 在之前&#xff0c;我向大家介绍了C语言中的一个常用的内存函数memcpy函数。如果你还没看的话&#…

Check Point 安全网关任意文件读取漏洞复现(CVE-2024-24919)

Check Point 安全网关任意文件读取漏洞复现(CVE-2024-24919) 1.漏洞描述 Check Point Security Gateways 是 Check Point Sofware 提供的一系列 网络安全Q解决方案。这些解决方案包括下一代防火墙(NGFW)、数据中心安全网关和 A1驱动的量子网关&#xff0c;旨在为企业提供针对…

反思 GTC 和 OFC 2024:没有一刀切的方法,但上市时间是关键!

在GTC 2024期间&#xff0c;英伟达宣布了最新的Blackwell B200张量核心GPU&#xff0c;旨在为万亿参数的AI大型语言模型提供支持。Blackwell B200需要先进的800Gbps网络&#xff0c;完全符合在AI工作负载的AI网络报告中概述的预测。随着人工智能工作负载的流量预计每两年增长10…

销量逆袭!敦煌店铺如何靠自养号测评轻松引爆市场?

对于众多卖家而言&#xff0c;踏入中国领先的B2B跨境电商平台&#xff0c;如同步入了充满无尽机会的金矿。然而&#xff0c;有些卖家在平台上努力经营&#xff0c;但订单却寥寥无几。那么&#xff0c;究竟是什么原因导致了这种情况&#xff1f;接下来&#xff0c;我们将结合实际…

小程序webView 实现小程序内嵌H5页面

web-view | 微信开放文档 本案例新建了一个 webView页面 只渲染webView组件 配置路由,跳转页面的时候 前缀使用‘/subPages/webView/index?weburlhttps://xxxxx’ componentDidMount 的时候 获取路由中的 weburl 地址参数 async componentDidMount() {const router getCurre…

Coolmuster Android Assistant: 手机数据管理的全能助手

在数字化时代&#xff0c;智能手机不仅是通讯工具&#xff0c;更是个人数据的中心。随着数据量的不断增加&#xff0c;如何有效管理和保护这些数据成为了一个重要议题。Coolmuster Android Assistant应运而生&#xff0c;它是一款专为安卓用户设计的综合数据管理软件&#xff0…

九部门联合发文知识产权保护体系建设,微版权打造全链条知产保护

近日&#xff0c;国家知识产权局会同中央宣传部、最高人民法院、最高人民检察院、公安部、司法部、商务部、海关总署、国家市场监督管理总局等八部门联合印发《知识产权保护体系建设工程实施方案》(以下简称《方案》)&#xff0c;共同加强知识产权保护体系建设。 《方案》是新时…

使用vscode调试c++、python、torchrun、deepspeed程序

目录 调试模式启动(Launch)模式调试c++launch.jsontasks.json附加(Attach)模式调试pythondebug torchrun和deepspeedlaunch.json参考VSCode通过其强大的扩展生态系统和灵活的调试配置,为C++、Python以及特定工具链如TorchRun和DeepSpeed的调试提供了便捷的方式。通过合理配…

初识Spring Cloud Gateway

文章目录 一、网关简介1.1 网关提出的背景1.2 网关在微服务中的位置1.3 网关的技术选型1.4 补充 二、Spring Cloud Gateway的简介2.1 核心概念&#xff1a;路由&#xff08;Route&#xff09;2.2 核心概念&#xff1a;断言&#xff08;Predicate&#xff09;2.3 核心概念&#…