我看过一些类似的问题,但没有一个足够接近我的状态工作。我有三个文件:
- ContentView.swift
- VariableSetupModel.swift
- 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: VariableSetupModel
inContentNavView
.
传递viewModel
from使用.environmentObject(viewModel)
将ContentView
改为ContentNavView
,即将其添加到ContentView
,例如:VStack (alignment: .leading) {...}.environmentObject(viewModel)
注意,VariableSetupModel
不需要是单例,去掉static let shared = VariableSetupModel()
。
还要注意的是,viewModel
在SettingsView()
的使用中是可用的,SettingsView().environmentObject(viewModel)
另一种方法是从一个视图传递ObservedObject
到另一个视图。例如:
在ContentView
中声明@StateObject var viewModel = VariableSetupModel()
,在ContentNavView
中声明@ObservedObject var viewModel: VariableSetupModel
。
通过ContentNavView(viewModel: viewModel)
将viewModel
从ContentView
传递给ContentNavView
。