使用 SwiftUI + Combine + MVVM 进行 GUI 编程
课题
- 程序界面由3个文本编辑框和1个文本标签组成。
- 要求文本标签实时显示3个文本编辑框所输入的数字之和。
- 文本编辑框输入的不是合法数字时,将其值视为0。
- 3个文本编辑框的初值分别为1,2,3。
创建工程
打开 Xcode,File / New / Project..
在 New Project 向导的第1页,选 iOS / App
在向导的第2页的填上 Product Name: SwiftUIExample,interface 选 SwiftUI
在向导的第3页选择任意文件夹点击 Create 按钮创建工程
使用 MVVM 的解决方案
在工程中添加 NumbersViewModel.swift 文件,内容如下:
import Foundation
import Combine
class NumbersViewModel: ObservableObject {
@Published
var number1 = "1"
@Published
var number2 = "2"
@Published
var number3 = "3"
@Published
var result = ""
init() {
$number1.combineLatest($number2, $number3)
.map { String((Int($0) ?? 0) + (Int($1) ?? 0) + (Int($2) ?? 0)) }
.assign(to: &$result)
}
}
配置 UI
在工程中添加 NumbersModifier.swift 文件,内容如下:
import SwiftUI
struct LeftModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding(8)
.multilineTextAlignment(.trailing)
.frame(width: 150, alignment: .trailing)
}
}
struct RightModifier: ViewModifier {
func body(content: Content) -> some View {
content
.modifier(LeftModifier())
.keyboardType(.numberPad)
.overlay(
RoundedRectangle(cornerRadius: 14)
.stroke(Color.green, lineWidth: 2)
)
}
}
打开 ContentView.swift 文件,将内容改为:
import SwiftUI
struct ContentView: View {
@StateObject var vm = NumbersViewModel()
var body: some View {
VStack {
HStack {
Text("")
.modifier(LeftModifier())
TextField("Number1", text: $vm.number1)
.modifier(RightModifier())
}
HStack {
Text("")
.modifier(LeftModifier())
TextField("Number2", text: $vm.number2)
.modifier(RightModifier())
}
HStack {
Text("+")
.modifier(LeftModifier())
TextField("Number3", text: $vm.number3)
.modifier(RightModifier())
}
Divider()
HStack {
Text("")
.modifier(LeftModifier())
TextField("Result", text: $vm.result)
.disabled(true)
.modifier(RightModifier())
}
}.frame(width: 200, height: 200, alignment: .center)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}