如何解决对两个独立但半关联的视图模型的视图之间的特定状态变化进行通信/反应
我有一个视图,它由两个子视图组成,它们具有 1) 独立的内部状态和 2) 对任何相关视图(即彼此)都值得注意的高级状态。也就是说,一个人的高层状态的变化应该触发另一个人重新考虑/改变自己的状态。想象一下——为了保持简单/通用——一个页眉有一组按钮,这些按钮根据页脚中选择的选项而改变。另一方面,页眉中有一个按钮可以退出活动状态并将其重置回原始状态(因此页脚也是如此)。
通过为每个视图的视图模型采用共享的通用实例,我设法方便地实现了这一点。例如,页眉观察页脚视图模型的变化,因此能够对页脚高级状态的变化做出反应。但是,考虑到页脚具有其他内部状态(即与页眉无关,但对于观察其自身视图模型更改的页脚视图而言是必需的),每次发生任何更改时都会重新渲染页眉视图,而不管相关性如何,到页脚视图。实际上,至少在我看来,我不会注意到任何视觉上的问题,但我知道这是一种从根本上低效(且错误)的管理状态流的方法。并且如果这种不当行为普遍存在,那么性能可能会受到影响(可见)。
我所拥有的是:
struct HeaderView: View {
// MARK: Observers
@ObservedObject var viewModel: HeaderViewModel = HeaderViewModel.shared
@ObservedObject var footerViewModel: FooterViewModel = FooterViewModel.shared
// MARK: -
var body: some View {
VStack {
switch footerViewModel.state {
case 1: HeaderState1View()
case 2: HeaderState2View()
case 3: HeaderState3View()
}
Button("EXIT",action: {viewModel.reset()})
}
}
}
struct FooterView: View {
// MARK: Observers
@ObservedObject var viewModel: FooterViewModel = FooterViewModel.shared
// MARK: -
var body: some View {
Button("State 1",action: {viewModel.state(to: 1)})
.background(viewModel.state == 1 ? Color.red : Color.clear)
Button("State 2",action: {viewModel.reset()})
.background(viewModel.state == 2 ? Color.red : Color.clear)
Button("State 3",action: {viewModel.reset()})
.background(viewModel.state == 3 ? Color.red : Color.clear)
}
}
class HeaderViewModel: ObservableObject {
// ...
func reset() {
FooterViewModel.shared.reset()
// and other internal state changes
}
// ...
}
class FooterViewModel: ObservableObject {
@Published var state: Int = 1
// ...
func state(to state: Int) {
self.state = state
}
func reset() {
self.state = 1
}
// ...
}
每个视图模型都是在负责创建两者(和其他)的根级 ViewModel 中创建的。
class ViewModel {
var footer = FooterViewModel()
var header = HeaderViewModel()
// etc.
}
这是在@main 根结构中创建的:
@main
struct myApp: App {
// MARK: Variables
var viewModel = ViewModel()
// MARK: Layout
var body: some Scene {
return WindowGroup {
ContentView()
.environmentObject(viewModel)
}
}
}
struct ContentView: View {
// MARK: -
var body: some View {
VStack {
header
/// other views
footer
}
}
在不依赖页眉和页脚视图模型的共享实例的情况下,如上所述,实现我所追求的最合适/最有效的方法是什么?
更具体地说/更清楚,例如,如果页眉和页脚视图创建了它们各自视图模型的@StateObject,即
@StateObject var viewModel: FooterViewModel = FooterViewModel() /// in FooterView.swift
@StateObject var viewModel: HeaderViewModel = HeaderViewModel() /// in HeaderView.swift
如何让 HeaderView 中的任何更改与 FooterView 创建的 FooterViewModel 实例进行通信?
编辑:
我想实现这一点的一种方法是创建第三个视图模型,该模型包含已发布的共享状态,并且在初始化时将其传递到两个视图中。但是想象一下,需要在视图之间共享不止一个已发布的属性,并且混合中还有另一种视图只需要访问其中一个——我会创建两个共享视图模型吗:一个与发布者共享所有 3 和另一个之间的属性与 2 的属性?似乎不是一个实用的策略。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。