I'm trying to get a NavigationSplitView working where on the iPhone in compact/portrait mode when you go to the detail view there is a '.sheet' that is available only on that view, and when you navigate back it goes away. I'm coming across a few issues and I'm not sure what I'm doing wrong.
1 - preferredCompactColumn seems to be ignored at the start in my minimal reproducible sample, it always starts into the detail view. fixed thanks to link provided by sweeper - set to nil
2 - the sheet initially appears over the sidebar view at first launch despite being attached to the detail view. I get an error message... "swiftui sheet Presenting view controller from detached view controller is not supported, and may result in incorrect safe area insets and a corrupt root presentation. Make sure is in the view controller hierarchy before presenting from it. Will become a hard exception in a future release."
Minimal Reproducible Code below.
import SwiftUI
// simple sidebar for testing
struct SideBarView: View {
@State private var selectedInt: Int? = nil
var body: some View {
List(1...3, id: \.self, selection: $selectedInt) { int in
NavigationLink("Row \(int)", value: int)
}
}
}
// Detail View with a permanent bottom sheet
struct DetailView: View {
@State var sheetVisible: Bool = false
// fill the space
var body: some View {
VStack {
Spacer()
Text("detail view")
Spacer()
}
.onAppear(perform: {
sheetVisible = true
})
.onDisappear(perform: {
sheetVisible = false
})
// show a bottom sheet that is for this view
// in this case I have dismiss disable but it seems to break regardless
.sheet(isPresented: $sheetVisible) {
Text("Bottom Sheet")
.presentationDetents([.fraction(0.15), .medium, .large])
.presentationDragIndicator(.visible)
.interactiveDismissDisabled()
.presentationBackgroundInteraction(
.enabled(upThrough: .medium)
)
}
}
}
struct ContentView: View {
// bug? - this seems to be ignored at the start. Initial view is the detail
@State private var preferredColumn = NavigationSplitViewColumn.sidebar
var body: some View {
NavigationSplitView(
preferredCompactColumn: $preferredColumn)
{
// simple sidebar
SideBarView()
.navigationTitle("Sidebar")
} detail: {
// bug? - this detail view has a sheet displayed when active
// but it's causing issues with ehe split view and I'm not sure
// what I've done wrong with the setup
DetailView()
.navigationTitle("Details")
}
}
}

Tthe sheet appears even in the sidebar, because apparently the detail view's
onAppearis called as soon as the sidebar appears, even when the detail view hasn't appeared. I think this might not be intentional.To work around this, I thought of a way where you would need to shift the ownership of
selectedIntfromSideBarViewtoContentView. The idea is to let the detail view know about whether anything is selected in the sidebar.DetailViewnow knows whether itself is presented by checkinghasSelected. Only whenhasSelectedchanges from false to true (this means the user tapped a row in the sidebar), does it setsheetVisible = true.