SwiftUI:当观察到 object 从另一个文件更改时,视图不更新
SwiftUI: View not updating when Observed object changes from another file
我已经查看了一些类似的问题,但是 none 已经足够接近我的工作状态了。我有 3 个文件:
- ContentView.swift
- VariableSetupModel.swift
- ContentNavView.swift
以前所有 3 个中的代码都在一个文件 (ContentView) 中。我现在正在努力将其拆分以使代码更清晰。我是一个相当新手 iOS 的开发人员。我将所有变量移至 VariableSetupModel 并使其正常工作。我引用该文件中的值,它们更新,并 return 到 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
变化反映在不同的视图中,下面是一个示例,其主要思想是在所有不同的视图中使用一个真实来源:
在 ContentView
中声明 @StateObject var viewModel = VariableSetupModel()
并且
@EnvironmentObject var viewModel: VariableSetupModel
在 ContentNavView
.
通过 viewModel
来自
ContentView
to ContentNavView
using .environmentObject(viewModel)
, 即把这个加到ContentView
, eg: VStack (alignment: .leading) {...}.environmentObject(viewModel)
注意,VariableSetupModel
不需要是单例,去掉static let shared = VariableSetupModel()
。
另请注意,要在 SettingsView()
中使用 viewModel
,SettingsView().environmentObject(viewModel)
另一种方法是将 ObservedObject
从一个视图传递到另一个视图。
例如:
在ContentView
和
中声明@StateObject var viewModel = VariableSetupModel()
@ObservedObject var viewModel: VariableSetupModel
在 ContentNavView
.
使用 ContentNavView(viewModel: viewModel)
.
将 viewModel
从 ContentView
传递到 ContentNavView
我已经查看了一些类似的问题,但是 none 已经足够接近我的工作状态了。我有 3 个文件:
- ContentView.swift
- VariableSetupModel.swift
- ContentNavView.swift
以前所有 3 个中的代码都在一个文件 (ContentView) 中。我现在正在努力将其拆分以使代码更清晰。我是一个相当新手 iOS 的开发人员。我将所有变量移至 VariableSetupModel 并使其正常工作。我引用该文件中的值,它们更新,并 return 到 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
变化反映在不同的视图中,下面是一个示例,其主要思想是在所有不同的视图中使用一个真实来源:
在 ContentView
中声明 @StateObject var viewModel = VariableSetupModel()
并且
@EnvironmentObject var viewModel: VariableSetupModel
在 ContentNavView
.
通过 viewModel
来自
ContentView
to ContentNavView
using .environmentObject(viewModel)
, 即把这个加到ContentView
, eg: VStack (alignment: .leading) {...}.environmentObject(viewModel)
注意,VariableSetupModel
不需要是单例,去掉static let shared = VariableSetupModel()
。
另请注意,要在 SettingsView()
中使用 viewModel
,SettingsView().environmentObject(viewModel)
另一种方法是将 ObservedObject
从一个视图传递到另一个视图。
例如:
在ContentView
和
中声明@StateObject var viewModel = VariableSetupModel()
@ObservedObject var viewModel: VariableSetupModel
在 ContentNavView
.
使用 ContentNavView(viewModel: viewModel)
.
viewModel
从 ContentView
传递到 ContentNavView