如何在 SwiftUI 中实现 MVVM 模式?视图不会重新渲染
Posted
技术标签:
【中文标题】如何在 SwiftUI 中实现 MVVM 模式?视图不会重新渲染【英文标题】:How to implement the MVVM-Pattern in SwiftUI? The View is not re-rendered 【发布时间】:2020-01-06 12:26:17 【问题描述】:我正在学习 SwiftUI 并尝试使用 MVVM 模式实现一个简单的 Timer。但是 Timer 的视图不会重新渲染。有什么问题?
// Timer Model
import Foundation
class TimerModel
let label: String = "Counter"
var count: Int = 0
// Timer View Model
import Foundation
import SwiftUI
import Combine
class TimerViewModel: ObservableObject
@Published var timerModel: TimerModel = TimerModel()
var label: String
return self.timerModel.label
var count: Int
return self.timerModel.count
func startTimer()
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) (timer) in
DispatchQueue.main.async
self.timerModel.count += 1
// Timer View
import SwiftUI
import Combine
struct TimerView: View
@ObservedObject var timerViewModel: TimerViewModel
init()
self.timerViewModel = TimerViewModel()
var body: some View
VStack
Text("\(self.timerViewModel.label): \(self.timerViewModel.count)")
Button(action:
self.timerViewModel.startTimer()
, label:
Text("Start")
)
struct TimerView_Previews: PreviewProvider
static var previews: some View
TimerView()
// Content View
import SwiftUI
struct ContentView: View
var body: some View
TimerView()
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
Timer View Model 中 Timer Model 的 count 属性每秒钟改变一次,但 Timer View 不会重新渲染。感谢您提供实现 MVVM 模式的任何想法。
【问题讨论】:
【参考方案1】:最简单的就是把模型改成值类型
struct TimerModel
let label: String = "Counter"
var count: Int = 0
【讨论】:
谢谢你,阿斯佩里。计数器正在运行:)。上面的代码是在大型项目中实现 MVVM 模式的正确方法吗?为什么我需要值类型结构而不是引用类型类? 如果你改变结构的属性,整个结构都会改变,所以@Published
wrapper 工作,如果对象(引用类型)的属性改变,对象(实际上是引用)不会改变,所以包装器不发布任何事件。总的来说方法是对的。以上是关于如何在 SwiftUI 中实现 MVVM 模式?视图不会重新渲染的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter Native Android 代码中实现 MVVM 架构