利用SwiftUI、Combine和MVVM设计图形用户界面
目标
- 构建一个包含三个输入框和一个标签的界面。
- 标签需实时显示三个输入框中数字的总和。
- 输入非数字时,视为0处理。
- 初始化时,三个输入框分别预设值为1, 2, 3。
工程设置
启动Xcode,依次选择File / New / Project... 在新建项目向导的第一步,选择iOS / App 第二步中填写Product Name: SwiftUIDemo,并选择SwiftUI作为界面类型 最后,在第三步中选择保存位置并点击Create创建工程
MVVM模式实现
新增NumberHandler.swift文件至项目,代码如下:
import Foundation
import Combine
class NumberHandler: ObservableObject {
@Published var firstInput = "1"
@Published var secondInput = "2"
@Published var thirdInput = "3"
@Published var sumResult = ""
init() {
Publishers.CombineLatest3($firstInput, $secondInput, $thirdInput)
.map { "\(($0 as NSString).integerValue + ($1 as NSString).integerValue + ($2 as NSString).integerValue)" }
.assign(to: &$sumResult)
}
}
用户界面定制
添加TextFieldStyler.swift文件,内容如下:
import SwiftUI
struct FieldStyle: ViewModifier {
func body(content: Content) -> some View {
content
.padding(8)
.multilineTextAlignment(.trailing)
.frame(width: 150, alignment: .trailing)
}
}
struct NumericFieldStyle: ViewModifier {
func body(content: Content) -> some View {
content
.modifier(FieldStyle())
.keyboardType(.numberPad)
.overlay(
RoundedRectangle(cornerRadius: 14)
.stroke(Color.blue, lineWidth: 2)
)
}
}
编辑MainView.swift文件,更新为:
import SwiftUI
struct MainView: View {
@StateObject private var handler = NumberHandler()
var body: some View {
VStack {
HStack {
Text("")
.modifier(FieldStyle())
TextField("First", text: $handler.firstInput)
.modifier(NumericFieldStyle())
}
HStack {
Text("")
.modifier(FieldStyle())
TextField("Second", text: $handler.secondInput)
.modifier(NumericFieldStyle())
}
HStack {
Text("+")
.modifier(FieldStyle())
TextField("Third", text: $handler.thirdInput)
.modifier(NumericFieldStyle())
}
Divider()
HStack {
Text("")
.modifier(FieldStyle())
TextField("Total", text: $handler.sumResult)
.disabled(true)
.modifier(NumericFieldStyle())
}
}.frame(width: 200, height: 200, alignment: .center)
}
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}