如何让 SwiftUI SidebarMenu 每次都显示相同的 DetailView 而不是创建一个新的(在 macOS 上)

Posted

技术标签:

【中文标题】如何让 SwiftUI SidebarMenu 每次都显示相同的 DetailView 而不是创建一个新的(在 macOS 上)【英文标题】:How can I get a SwiftUI SidebarMenu to display the same DetailView each time rather than creating a new one (on macOS) 【发布时间】:2020-03-13 10:15:12 【问题描述】:

我有一个 macOS Master/Detail 应用程序,它使用 NavigationView,左侧面板中有侧边栏菜单,右侧面板中有一系列详细视图。

我想在用户选择不同的侧边栏菜单选项时保留详细视图,这样如果用户通过选择以前的选择菜单选项切换回来,那么应用程序应该显示最初创建的详细视图以及任何用户更改或选择。

目前,Swifui在选择菜单选项时从头开始创建一个新视图,而不是显示先前创建的。例如,如果详细视图有一个 ListView 并且用户之前选择了一个项目,那么这个选择会像之前的任何滚动位置一样丢失。

有没有办法用 SwiftUI 实现这一点。

【问题讨论】:

目前 SwiftUI 不支持滚动位置持久性,但从概念上讲,其他所有内容(如选择、用户更改)都应该存储在模型中,当它再次出现时将由视图呈现.所以,你宁愿需要重新考虑你的应用程序的设计。而且您无法保留查看它只是结构,值。 嗯,这就是我所怀疑的,所以使用“@State”实际上是没用的,因为如果迷路了,需要使用“@EnvironmentObject”或其他东西来保留用户会话的状态,而应用程序正在运行。 @State 仅用于视图内部状态,例如隐藏/显示某些内容、突出显示等,但持久视图模型应该存储在外部某处,是的,它可能是 @EnvironmentObject、@987654323 @(到 ObservableObject)等 不得不将这个视图状态存储在某处,而不是简单地保留视图并能够显示/隐藏视图的相同实例(如果已经创建了一个实例),这似乎太过分了。我想我可以尝试使用 TabbedView 来查看是否会保留标签内容视图。 【参考方案1】:

目前看来 SwiftUI 不支持这个。以下是一些类似的问题:

Tabbed view loses state

Tabbed view resets state

【讨论】:

【参考方案2】:

SwiftUI 从模型创建视图,例如一个绑定。存储选择和滚动位置,以便可以完全按原样重新创建视图。由于视图可能会更新为不同的大小,因此最好将可见项目的 ID 存储在顶部并滚动到该 ID 而不是偏移量。

旧的 UITabBarController 保持其子视图控制器活动的方式可能被认为是一个错误和内存浪费。

【讨论】:

您可以在列表中绑定所选项目,但列表不会滚动到所选项目,似乎没有 API 可以做到这一点。

以上是关于如何让 SwiftUI SidebarMenu 每次都显示相同的 DetailView 而不是创建一个新的(在 macOS 上)的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI如何让绑定到同一个状态的多个TextField呈现出不同输入行为

SwiftUI如何让绑定到同一个状态的多个TextField呈现出不同输入行为

Shiny:Shiny Dashboard (sidebarMenu) 中的 renderMenu 和 observeEvent 冲突

从 Shiny 中的 sideBarMenu 和 radioButton 选择时不显示图表

SwiftUI:如何根据日期每天显示一个新视图,而以前的视图持续一周

单击按钮时 Shinydashboard 的 SidebarMenu 中的折叠(关闭)菜单