今天開始我們要來介紹App 常用功能,首先會從專案架構講起。
提到專案架構就不得不提到MVVM,所以今天我們會針對MVVM進行介紹。
MVVM 是一種常見的專案架構模式,主要目的是 分離畫面 (UI) 與邏輯 (Logic),降低耦合、方便測試,讓程式更乾淨、可維護。
MVVM 分成三層:
好處:
在 MVVM 架構 中,ViewModel 的責任就是 管理狀態 並 通知 View 更新。
而在 SwiftUI 中,最常見的方式是搭配 Combine 框架:
@Published
發布狀態變更@StateObject
或 @ObservedObject
來接收資料更新import SwiftUI
import Combine
class CounterViewModel: ObservableObject {
// 使用 @Published 讓數值改變時能發出通知
@Published var count = 0
func increment() {
count += 1
}
}
struct CounterView: View {
// 使用 @StateObject 讓 View 訂閱 ViewModel 的資料流
@StateObject var viewModel = CounterViewModel()
var body: some View {
VStack {
Text("目前數字:\(viewModel.count)")
.font(.largeTitle)
Button("加一") {
viewModel.increment()
}
}
}
}
@Published var count
是一個 Publisher。increment()
改變數值時,count
會透過 Combine 發出 新的值。@StateObject
自動訂閱這個 Publisher,讓 View 收到新值並重新渲染。ViewModel
import SwiftUI
import Combine
class LoginViewModel: ObservableObject {
// 使用者輸入
@Published var username: String = ""
@Published var password: String = ""
// 狀態
@Published var loginMessage: String = ""
func login() {
if username == "admin" && password == "1234" {
loginMessage = "登入成功"
} else {
loginMessage = "帳號或密碼錯誤"
}
}
}
View
struct LoginView: View {
@StateObject private var viewModel = LoginViewModel()
var body: some View {
VStack(spacing: 20) {
TextField("帳號", text: $viewModel.username)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.horizontal)
SecureField("密碼", text: $viewModel.password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.horizontal)
Button("登入") {
viewModel.login()
}
.padding()
Text(viewModel.loginMessage)
.foregroundColor(.blue)
}
.padding()
}
}
登入成功
登入失敗
@Published username
、@Published password
發出更新。loginMessage
,畫面立即反映結果。LoginViewModel
,負責處理登入邏輯LoginView
,負責顯示 UI 並觸發事件@Published
、@StateObject
、@ObservedObject
) 來建立資料流明天預計會介紹第三方套件,讓開發更快速、更彈性。