Change Modality of Sheets in SwiftUI

Is it possible to use create a "nonmodal sheet" as described in the Human Interface Guidelines and as seen in apps like Maps using SwiftUI's .sheet and the new .presentationDetents modifier in iOS 16. By default, the content behind the sheet is not interactive.

Is there a built in modifier or modality style that can be applied to the sheet to allow for interactive content behind the sheet?

+1 to this.

I am trying to present a "drawer" (read: sheet with presentationDetents()) on top of another View. Both the parent and the drawer should be interactive simultaneously. Currently, it appears that any time a sheet is displayed, it s forced to be modal, as @aaronjedwards noted.

This means my really-crummy implementation of a drawer will have to live on, much to my dismay, even though the new presentationDetents() API seems made for my use-case.

I filed FB10636765 on this issue.

Yes there is a way but only iOS 16.4 with Xcode 14.3 you want .presentationBackgroundInteraction(.enabled())

You can use it based on the detents like this:

.presentationBackgroundInteraction(.enabled(upThrough: .medium))

This will allow you to interact with the content behind the sheet.

Playground code here for that.


import SwiftUI
import PlaygroundSupport

struct Donut: View {
    var body: some View {
        VStack {
            Button("Tap me", action: {
                debugPrint("button tapped")
            })
            .offset(y: 30)
            .foregroundColor(.white)
            
            
            Circle()
                .frame(width: 200, height: 200)
                .foregroundColor(.yellow)
                .padding(.top, 72)
                .padding(.bottom, 200)
        }
    }
}

struct NavBar: View {
    var body: some View {
        Rectangle()
            .frame(maxWidth: .infinity)
            .frame(height: 30)
            .background(.white)
    }
}

struct Feed: View {
    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                ForEach(0..<14) { _ in
                    Text("Feed view")
                }
            }
            
        }
        .padding(.top, 20)
    }
}

struct Main: View {
    var body: some View {
        ZStack(alignment: .top) {
            NavBar()
            Donut()
        }
        .sheet(isPresented: .constant(true)) {
            Feed()
                .interactiveDismissDisabled(true)
                .presentationDetents([.fraction(0.4), .large])
                .presentationDragIndicator(.visible) // will always be true when you have 2 detents
                .presentationBackgroundInteraction(.enabled(upThrough: .medium)) // <- this is the magic property
        }
        .background(.green)
    }
}

PlaygroundPage.current.setLiveView(Main())

Change Modality of Sheets in SwiftUI
 
 
Q