SwiftUI:当观察对象从另一个文件更改时,视图不更新



我看过一些类似的问题,但没有一个足够接近我的状态工作。我有三个文件:

  1. ContentView.swift
  2. VariableSetupModel.swift
  3. ContentNavView.swift

以前,所有3个代码都在一个文件(ContentView)中。我现在正在将其拆分,以使代码更清晰。我是一个相当新手的iOS开发者。我将所有变量移动到VariableSetupModel中,并使其正常工作。我在该文件中引用值,它们更新,并返回到ContentView更新视图。

现在我正在将同一页面上的视图拆分为多个文件,从导航开始。视图显示出来,在页面第一次打开时正确地从VariableSetupModel读取值。但是当这个值从ContentView中的按钮改变时,它不会在ContentNavView中更新视图上的标题。下面是我的代码的简化版本:

ContentView.swift

struct ContentView: View {
//Pull in variables from "VariableSetupModel"
@ObservedObject var viewModel = VariableSetupModel()

@State var counter:Int = 0

var body: some View {
//Main Views
VStack (alignment: .leading) {

// MARK: Climbs-Title
ContentNavView()
}
}
Button(action: {
if viewModel.toggleListGraphs == "graph" {
viewModel.toggleListGraphs = "list"
}else{
viewModel.toggleListGraphs = "graph"
}        
}) {
Image(systemName: "list.bullet.below.rectangle")
.font(.title)
}
}

VariableSetupModel.swift

final class VariableSetupModel: ObservableObject {
static let shared = VariableSetupModel()
//Visuals
@Published var toggleListGraphs = "graph"
}

ContentNavView.swift

struct ContentNavView: View {
//Pull in variables from "VariableSetupModel"
@ObservedObject var viewModel = VariableSetupModel()
//var viewModel = VariableSetupModel.shared

var body: some View {
HStack{
if viewModel.toggleListGraphs == "graph"{
Text("All Sends")
.font(.title)
.padding(.horizontal)
}else{
Text("All Climbs")
.font(.title)
.padding(.horizontal)
}

Spacer()

Button(action: {
viewModel.showSettingsModal = true
}) {
Image("logoIcon")
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 35, height: 35)
}.padding().foregroundColor(Color("whiteblack"))
}.sheet(isPresented: $viewModel.showSettingsModal, onDismiss: {
//print(viewModel.showSettingsModal)
}) {
SettingsView()
}
}
}

有很多方法可以在不同的视图中反映viewModel的变化,下面是一个例子,其主要思想是在所有不同的视图中使用一个事实来源:

声明@StateObject var viewModel = VariableSetupModel()ContentView@EnvironmentObject var viewModel: VariableSetupModelinContentNavView.

传递viewModelfrom使用.environmentObject(viewModel)ContentView改为ContentNavView,即将其添加到ContentView,例如:VStack (alignment: .leading) {...}.environmentObject(viewModel)

注意,VariableSetupModel不需要是单例,去掉static let shared = VariableSetupModel()

还要注意的是,viewModelSettingsView()的使用中是可用的,SettingsView().environmentObject(viewModel)

另一种方法是从一个视图传递ObservedObject到另一个视图。例如:

ContentView中声明@StateObject var viewModel = VariableSetupModel(),在ContentNavView中声明@ObservedObject var viewModel: VariableSetupModel

通过ContentNavView(viewModel: viewModel)viewModelContentView传递给ContentNavView

相关内容

  • 没有找到相关文章

最新更新