Reputation: 1
Many popular apps have the ability to navigate to a new view from a sheet. For example, in the comment sheets in Instagram and TikTok, pressing on the commenting user's icon pushes in a whole new view for the user's profile. Once that view is dismissed, it returns to the previous view, where the comments sheet is still open.
However, when I have a .navigationDestination
outside of the sheet, it does navigate but the sheet remains in place, on top of the views:
.sheet(isPresented: $presentSheet) {
VStack {
Button("Present new view") {
presentDestination = true
}
}
}
.navigationDestination(isPresented: $presentDestination) {
VStack {
Text("New view")
}
}
Alternatively if I place the navigationDestination
inside the view presented by .sheet
, this results in navigation only within the sheet. I would want the whole screen be replaced with the new screen, as usually happens.
Is this not possible with Apple's built-in sheet
?
Upvotes: 0
Views: 250
Reputation: 1
In the main view you invoke your sheet. Inside the sheetView you Embed the body in a NavigationStack and have your own set of destinations to call.
import SwiftUI
struct ParentView: View {
@State var openSheet = false
var body: some View {
Button("Show a sheet") {
openSheet = true
}
.sheet(isPresented: $openSheet) {
SheetView()
}
}
}
struct SheetView: View {
enum Destination: {
case view1
case view2
}
@State private var localRouter: [Destination] = []
var body: some View {
NavigationStack(path: $localRouter) {
destinationView(for: .view1)
.toolbar {
closeButton()
}
.navigationDestination(for: Destination.self, destination: { destination in
destinationView(for: destination)
.toolbar {
closeButton()
}
})
}
}
@ViewBuilder
private func destinationView(for destination: Destination) -> some View {
switch destination {
case .view1:
View1()
case .view2:
View2()
}
}
}
Upvotes: 0
Reputation: 36807
You could try this approach using a NavigationStack(path: $path)
and
dismiss()
to navigate to a new page
of the root view from action/selection
in the sheet.
Example code:
struct ContentView: View {
@State private var presentSheet = false
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path){
Text("ContentView")
Button("Show Sheet") {
presentSheet = true
}
.navigationDestination(for: String.self) { page in
if page == "Page1" {
VStack {
Text("Page1 view")
}
} else {
VStack {
Text("Page2 view")
}
}
}
}
.sheet(isPresented: $presentSheet) {
SheetView(path: $path)
}
}
}
struct SheetView: View {
@Environment(\.dismiss) var dismiss
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("SheetView")
Button("Present Page1 view") {
path.append("Page1")
dismiss()
}
}
}
}
Upvotes: 1