【问题标题】:How to implement the MVVM-Pattern in SwiftUI? The View is not re-rendered如何在 SwiftUI 中实现 MVVM 模式?视图不会重新渲染
【发布时间】: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 模式的任何想法。

【问题讨论】:

    标签: swift xcode mvvm swiftui


    【解决方案1】:

    最简单的就是把模型改成值类型

    struct TimerModel {
        let label: String = "Counter"
        var count: Int = 0
    }
    

    【讨论】:

    • 谢谢你,阿斯佩里。计数器正在运行:)。上面的代码是在大型项目中实现 MVVM 模式的正确方法吗?为什么我需要值类型结构而不是引用类型类?
    • 如果你改变结构的属性,整个结构都会改变,所以@Published wrapper 工作,如果对象(引用类型)的属性改变,对象(实际上是引用)不会改变,所以包装器不发布任何事件。总的来说方法是对的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    相关资源
    最近更新 更多