3

I have a macOS Master/Detail app that uses a NavigationView with a sidebar menu in the left panel and a range of detail views in the right panel.

I want to retain the detail views when a user selected a different sidebar menu option such that if the user switches back by selecting a previously selection menu option then the app should display the originally created detail view with any user changes or selections.

Currently it seems that SwiftUI creates a new view from scratch when a menu option is selected rather than just displaying the previously created one. For example if the detail view has a ListView and the user previously selected an item then this selection gets lost as does any previous scroll position.

Is there anyway to achieve this with SwiftUI.

Duncan Groenewald
  • 8,496
  • 6
  • 41
  • 76
  • Scroll position persistency is not supported at the moment by SwiftUI, but everything else (like selection, user changes) should be, by concept, stored in model, which will be rendered by view when it appears again. So, you'd rather need to rethink design on your app. And you are not able to *retain* view it is just struct, value. – Asperi Mar 13 '20 at 10:45
  • Hmm that's what I suspected, so use of "@State" is actually useless because if gets lost and one would need to use "@EnvironmentObject" or something else to retain the state of the users session while the app is running. – Duncan Groenewald Mar 13 '20 at 11:12
  • `@State` is intended for view internal state only, like hide/show something, highlight, etc. but persistent view model should be stored somewhere outside, yes, it might be `@EnvironmentObject`, `@ObservedObject` (to ObservableObject), etc. – Asperi Mar 13 '20 at 11:28
  • It seems massive overkill to have to store this view state somewhere rather than simply retaining the view and being able to display/hide the same instance of the view if one has already been created. I guess I could try using a TabbedView to see if that will retain the tabs content views. – Duncan Groenewald Mar 13 '20 at 19:14

2 Answers2

0

It seems that SwiftUI does not support this at this time. Here are a few similar questions:

Tabbed view loses state

Tabbed view resets state

Duncan Groenewald
  • 8,496
  • 6
  • 41
  • 76
0

SwiftUI creates the view from a model, e.g. a binding. Store the selections and scroll positions so the view can be re-created exactly as it was. Since the view might get updated as a different size it would be better to store the ID of the item visible at the top and scroll to that rather than an offset.

The way the old UITabBarController kept its child view controllers alive could be considered a bug and a waste of memory.

malhal
  • 26,330
  • 7
  • 115
  • 133