iOS Development

ios – SwiftUI: Preserve state of backside sheet when one other sheet is opened

Spread the love


I’ve a really complicated app and I’ve created a pattern app to elucidate my downside.

My app has a backside sheet (BottomSheetView) which has navigation locations to drill into different views throughout the sheet. There’s additionally a button (data button) throughout the app which when clicked opens one other sheet.

As an instance I faucet on a button inside BottomSheetView which opens BottomSheetSubView as navigation vacation spot. Then faucet on the data button on the app which opens one other sheet(InfoView and InfoSubView) over BottomSheetView. Once I cancel out of this data sheet view, I discover that backside sheet’s state modifications i.e. backside sheet reveals BottomSheetView as an alternative of BottomSheetSubView.

I need to proceed exhibiting BottomSheetSubView since that was the view earlier than I opened data view. How can I preserve the state of backside sheet the identical?

Sharing my code under. You in all probability should run it to grasp the issue.

import SwiftUI
import Basis

class MainViewModel: ObservableObject {
    @Revealed var showBottomPanel = false
    @Revealed var selectedDetent: PresentationDetent = .fraction(0.25)
}

struct ContentView: View {
    @StateObject var mainViewModel: MainViewModel = MainViewModel()
    
    var physique: some View {
        NavigationStack {
            VStack {
                Textual content("That is the principle view").padding(.high, 100.0)
                Spacer()
            }
            .onAppear {
                mainViewModel.showBottomPanel = true
            }
            .overlay(alignment: .bottomTrailing) {
                self.infoView
            }
            .sheet(isPresented: $mainViewModel.showBottomPanel) {
                ZStack {
                    Coloration.grey.opacity(0.5)
                    BottomSheetView().padding(.high, 15.0).environmentObject(mainViewModel)
                }
            }
        }
    }
    
    non-public var infoView: some View {
        InfoView().padding(.backside, 210.0).padding(.trailing, 10.0)
    }
}

// MARK: View's associated to backside sheet.

struct BottomSheetView: View {
    @EnvironmentObject var mainViewModel: MainViewModel
    @State var showSubView = false
    var physique: some View {
        NavigationStack {
            ZStack {
                Coloration.grey.opacity(0.5).edgesIgnoringSafeArea(.all)
                VStack {
                    Button { self.showSubView = true } label: {
                        Textual content("Click on Me")
                    }
                }
                .navigationDestination(isPresented: $showSubView) {
                    BottomSheetSubView()
                }
            }
        }
        .presentationDetents([.fraction(0.25), .large], choice: $mainViewModel.selectedDetent)
        .interactiveDismissDisabled(true)
        .presentationBackgroundInteraction(.enabled)
    }
}

struct BottomSheetSubView: View {
    var physique: some View {
        VStack {
            Textual content("This can be a sub view and may keep lively.")
        }
    }
}

// MARK: View's associated to data view/data button

struct InfoView: View {
    @State var showInfoSubView = false
    
    var physique: some View {
        VStack(spacing: 0) {
            Button {
                showInfoSubView = true
            } label: {
                Picture(systemName: "data.circle.fill").resizable().foregroundColor(.blue).body(width: 30, top: 30)
            }
        }
        .sheet(isPresented: $showInfoSubView) {
            InfoSubView()
        }
    }
}

struct InfoSubView: View {
    @Atmosphere(.presentationMode) non-public var presentationMode
    
    var physique: some View {
        NavigationStack {
            VStack {
                Textual content("That is data sub view... faucet on cancel button")
            }
            .presentationDetents([.large])
            .interactiveDismissDisabled(true)
            .presentationBackgroundInteraction(.enabled)
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button {
                        presentationMode.wrappedValue.dismiss()
                    } label: {
                        Textual content("Cancel").font(.physique)
                    }
                }
            }
        }
    }
}

Steps to provide the issue:

  • Run the code above.
  • Faucet on “Click on Me” on the underside panel which is able to navigate it to subview which says – “This can be a sub view and may keep lively”.
  • Now do not do something with backside panel, however faucet on data button to open data view.
  • As soon as data view is opened, faucet ‘Cancel’ on high left of this panel to shut the data sheet.
  • Discover the underside panel goes again to “Click on Me” view as an alternative of “This can be a sub view and may keep lively” view.

I want to preserve “This can be a sub view and may keep lively” lively within the backside panel as soon as data view is closed. How can I obtain this?

One thought on “ios – SwiftUI: Preserve state of backside sheet when one other sheet is opened

Leave a Reply

Your email address will not be published. Required fields are marked *