frzi / swiftui-router

Path-based routing in SwiftUI
MIT License
900 stars 43 forks source link

State of views from the back stack is not saved #55

Open PhilipDukhov opened 2 years ago

PhilipDukhov commented 2 years ago

I expect back stack to work same as in system navigation: view states from the back stack should be saved.

It includes saving @State and @StateObject annotated objects, but I can think of workaround how I can store them manually.

The main think is scroll view position - in SwiftUI it's impossible to scroll to contentOffset, if we're using basic ScrollView, so I can't even store scroll position and restore it when view appears, unless I write my own scroll view.

Here's a basic example to reproduce:

  1. Run the app
  2. Scroll the list
  3. Click Next button to navigate
  4. Click Back button to navigate back
  5. Scroll position is reset.
@EnvironmentObject private var navigator: Navigator

var body: some View {
    SwitchRoutes {
        Route("/settings") {
            Button {
                navigator.goBack()
            } label: {
                Text("back")
            }
        }
        Route {
            Text(navigator.path)
            Button {
                navigator.navigate("/settings")
            } label: {
                Text("next")
            }
            ScrollView {
                ForEach(0..<100, id: \.self) { i in
                    Text("\(i)")
                }
            }
        }
    }
}

A possible workaround would be having all the screens from the back stack in the view tree - e.g. in ZStack, one on top of an other one. But this for sure would break onAppear/onDisappear, as well as transitions.