当前位置:首页 > 技术 > 正文内容

基于 UIKit 与 Combine 的 MVVM 架构实时计算界面

访客 技术 2026年6月18日 1

功能需求

  • 界面包含三个输入框和一个结果显示标签。
  • 标签需动态展示三个输入框中数值的总和。
  • 若输入非数字内容,自动视为零处理。
  • 初始值分别为:第一个输入框为1,第二个为2,第三个为3。

项目初始化 在 Xcode 中选择 File > New > Project,创建 iOS 应用工程。 填写项目名称为 CombineExample,选择任意目录后点击 Create 完成创建。 随后关闭当前工程以进行后续配置。

集成 CombineCocoa 依赖 在项目导航器中选中工程名,右键选择 Add Packages...。 在搜索框中输入:https://github.com/CombineCommunity/CombineCocoa.git,回车后添加该包。 确认后,项目依赖列表将显示 CombineCocoa 0.4.0 已成功引入。

数据模型层设计 新建文件 NumbersViewModel.swift,定义视图模型逻辑:

import Foundation
import Combine

class NumbersViewModel: ObservableObject {
    @Published var inputA = "1"
    @Published var inputB = "2"
    @Published var inputC = "3"
    @Published var totalDisplay = ""

    init() {
        // 合并三个输入字段的值,转换为整数求和,并更新结果
        $inputA.combineLatest($inputB, $inputC)
            .map { first, second, third in
                let sum = (Int(first) ?? 0) + (Int(second) ?? 0) + (Int(third) ?? 0)
                return String(sum)
            }
            .assign(to: &$totalDisplay)
    }
}

界面布局设置 打开 Main.storyboard,在主视图控制器的根视图中拖入三个 UITextField 及一个 UILabel,按需排列。

绑定控件引用 在 ViewController.swift 中声明对应的 IBOutlet 属性:

@IBOutlet weak var textFieldA: UITextField!
@IBOutlet weak var textFieldB: UITextField!
@IBOutlet weak var textFieldC: UITextField!
@IBOutlet weak var resultLabel: UILabel!

使用 Assistant Editor 并按住 Control 键,分别将这些属性连接到对应组件。

实现 MVVM 数据流 在 ViewController 类中加入视图模型实例及绑定逻辑:

import UIKit
import Combine
import CombineCocoa

class ViewController: UIViewController {
    private var viewModel: NumbersViewModel!
    private var cancellables = Set<AnyCancellable>()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewModel = NumbersViewModel()

        // 反向绑定:视图模型变化 → 控件显示
        viewModel.$inputA.assign(to: \.text, on: textFieldA, owner: self).store(in: &cancellables)
        viewModel.$inputB.assign(to: \.text, on: textFieldB, owner: self).store(in: &cancellables)
        viewModel.$inputC.assign(to: \.text, on: textFieldC, owner: self).store(in: &cancellables)
        viewModel.$totalDisplay.assign(to: \.text, on: resultLabel, owner: self).store(in: &cancellables)

        // 正向绑定:用户输入 → 视图模型更新(过滤非空输入)
        textFieldA.textPublisher.compactMap { $0 }.assign(to: &viewModel.$inputA).store(in: &cancellables)
        textFieldB.textPublisher.compactMap { $0 }.assign(to: &viewModel.$inputB).store(in: &cancellables)
        textFieldC.textPublisher.compactMap { $0 }.assign(to: &viewModel.$inputC).store(in: &cancellables)
    }
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。