iosswiftswiftui

How to present sheet in SwiftUI to not cover specific View?


Is there any way to present sheet from SwiftUI to NOT TO cover specific View?

Any ideas?

My code:

struct DemoView: View {
    @State var isPresented = true
    var body: some View {
        ZStack {
            Color.brown
                .ignoresSafeArea()
            VStack {
                Spacer()
                Text("My bottom menu")
            }
        }
        .sheet(isPresented: $isPresented) {
            Text("my news page")
                .presentationDetents([.height(100), .fraction(0.9)])
                .interactiveDismissDisabled()
        }
    }
}

enter image description here enter image description here

What do I want to achieve?

I want to present sheet view from behind my "bottom menu". It is replacement for more complicated NavigationTabView;)


Solution

  • A sheet is always presented above other content, so it is not possible for the bottom menu to be above the sheet.

    However, it is possible to leave a "hole" in the background of a presentation, which would allow a view to show through.

    Unfortunately, it doesn't appear to be possible to interact with the view that shows in the hole, even if you apply .presentationBackgroundInteraction(.enabled), as this updated example illustrates:

    struct DemoView: View {
        @State private var isPresented = true
        @State private var bottomInset = CGFloat.zero
    
        var body: some View {
            ZStack {
                Color.brown
                    .ignoresSafeArea()
                VStack {
                    Spacer()
                    Text("My bottom menu")
                        .onTapGesture {
                            isPresented.toggle() // never toggles
                        }
                }
            }
            .onGeometryChange(for: CGFloat.self, of: \.safeAreaInsets.bottom) { inset in
                bottomInset = inset
            }
            .sheet(isPresented: $isPresented) {
                Text("my news page")
                    .padding(.bottom, 40)
                    .presentationBackgroundInteraction(.enabled)
                    .presentationDetents([.height(140), .fraction(0.9)])
                    .presentationBackground {
                        RoundedRectangle(cornerRadius: 10)
                            .fill(.background)
                            .padding(.bottom, bottomInset + 40)
                    }
                    .interactiveDismissDisabled()
            }
        }
    }
    

    Screenshot


    Possible workarounds: