SwiftUI 观察到的对象未更新

戴尔伯特

真的只是从 SwiftUI 开始,并试图了解 MVVM。

下面的代码显示了一个高度和 4 个切换按钮,到目前为止我只连接了 2 个。

主要向上和主要向下。

单击后,我在控制台中看到该值已按预期更改。

我没有看到主要显示更新以反映更改。

我尝试重构我的代码以将视图模型包含到每个 Struct 中,但仍然没有看到更改。

我想我已经涵盖了基础知识,但被难住了,我现在使用单个文件,但计划在我有一个工作模型时将模型和视图模型移动到单独的文件中。

谢谢你看。

import SwiftUI

/// This is our "ViewModel"
class setHeightViewModel: ObservableObject {
    struct ImperialAndMetric {
        var feet = 16
        var inches = 3
        var meters = 4
        var CM = 95
        var isMetric = true
    }
    
    // The model should be Private?
    // ToDo: Fix the private issue.
    @Published var model = ImperialAndMetric()
        
    // Our getters for the model
    var feet: Int { return model.feet }
    
    var inches: Int { return model.inches }
    
    var meters: Int { return model.meters }
    
    var cm: Int { return model.CM }
    
    var isMetric: Bool { return model.isMetric }
    
    /// Depending upon the selected mode, move the major unit up by one.
    func majorUp() {
        if isMetric == true {
            model.meters += 1
            print("Meters is now: \(meters)")
        } else {
            model.feet += 1
            print("Feet is now: \(feet)")
        }
    }
    
    /// Depending upon the selected mode, move the major unit down by one.
    func majorDown() {
        if isMetric == true {
            model.meters -= 1
            print("Meters is now: \(meters)")
        } else {
            model.feet -= 1
            print("Feet is now: \(feet)")
        }
    }
    
    /// Toggle the state of the display mode.
    func toggleMode() {
        model.isMetric = !isMetric
    }
}

// This is our View

struct ViewSetHeight: View {
    
    // UI will watch for changes for setHeihtVM now.
    @ObservedObject var setHeightVM = setHeightViewModel()
    
    var body: some View {
        NavigationView {
            Form {
                ModeArea(viewModel: setHeightVM)
                SelectionUp(viewModel: setHeightVM)
                
                // Show the correct height format
                if self.setHeightVM.isMetric == true {
                    ValueRowMetric(viewModel: self.setHeightVM)
                } else {
                    ValueRowImperial(viewModel: self.setHeightVM)
                }
                
                SelectionDown(viewModel: setHeightVM)
                
            }.navigationTitle("Set the height")
        }
        
    }
}

    struct ModeArea: View {
        var viewModel: setHeightViewModel
        
        var body: some View {
            Section {
                if viewModel.isMetric == true {
                    SwitchImperial(viewModel: viewModel)
                } else {
                    SwitchMetric(viewModel: viewModel)
                }
            }
        }
    }
    
    struct SwitchImperial: View {
        var viewModel: setHeightViewModel
        
        var body: some View {
            HStack {
                Button(action: {
                    print("Imperial Tapped")
                }, label: {
                    Text("Imperial").onTapGesture {
                        viewModel.toggleMode()
                    }
            })
                Spacer()
                Text("\(viewModel.feet)\'-\(viewModel.inches)\"").foregroundColor(.gray)
            }
        }
    }
        
    struct SwitchMetric: View {
        
        var viewModel: setHeightViewModel
        
        var body: some View {
            HStack {
                Button(action: {
                    print("Metric Tapped")
                }, label: {
                Text("Metric").onTapGesture {
                    viewModel.toggleMode()
                   }
            })
                Spacer()
                Text("\(viewModel.meters).\(viewModel.cm) m").foregroundColor(.gray)
            }
        }
    }

    struct SelectionUp: View {
        
        var viewModel: setHeightViewModel
        
        var body: some View {
            Section {
                HStack {
                        Button(action: {
                            print("Major Up Tapped")
                            viewModel.majorUp()
                        }, label: {
                            Image(systemName: "chevron.up").padding()
                        })
                    
                        Spacer()
                    
                    Button(action: {
                        print("Minor Up Tapped")
                    }, label: {
                        Image(systemName: "chevron.up").padding()
                    })
                }
            }
        }
    }

    struct ValueRowImperial: View {
        
        var viewModel: setHeightViewModel
        
        var body: some View {
            HStack {
                Spacer()
                Text(String(viewModel.feet)).accessibility(label: Text("Feet"))
                Text("\'").foregroundColor(Color.gray).padding(.horizontal, -10.0).padding(.top, -15.0)
                Text("-").foregroundColor(Color.gray).padding(.horizontal, -10.0)
                Text(String(viewModel.inches)).accessibility(label: Text("Inches"))
                Text("\"").foregroundColor(Color.gray).padding(.horizontal, -10.0).padding(.top, -15.0)
                Spacer()
            }.font(.largeTitle).padding(.zero)
        }
    }

    struct ValueRowMetric: View {
        
        var viewModel: setHeightViewModel
        
        
        var body: some View {
            HStack {
                Spacer()
                Text(String(viewModel.meters)).accessibility(label: Text("Meter"))
                Text(".").padding(.horizontal, -5.0).padding(.top, -15.0)
                Text(String(viewModel.cm)).accessibility(label: Text("CM"))
                Text("m").padding(.horizontal, -5.0).padding(.top, -15.0).font(.body)
                Spacer()
            }.font(.largeTitle)
        }
    }

    struct SelectionDown: View {
        
        var viewModel: setHeightViewModel
        
        var body: some View {
            Section {
                HStack {
                        Button(action: {
                            print("Major Down Tapped")
                            viewModel.majorDown()
                        }, label: {
                            Image(systemName: "chevron.down").padding()
                        })
                    
                        Spacer()
                    
                    Button(action: {
                        print("Minor Down Tapped")
                    }, label: {
                        Image(systemName: "chevron.down").padding()
                    })
                }
            }
        }
    }
工作犬

当您setHeightViewModel在各种视图中将接收为 var 时,您应该将其接收为ObservedObject.

我建议你试试这个,在 ViewSetHeight

@StateObject var setHeightVM = setHeightViewModel()  

在传递此模型的所有其他视图中,请使用:

@ObservedObject var viewModel: setHeightViewModel

ModeAreaSwitchImperialSwitchMetricSelectionUp,等...

或者,您可以使用@EnvironmentObject... 将 传递setHeightViewModel给需要它的所有视图。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章