Представление листа с помощью NavigationStack в SwiftUI
Я пытаюсь выяснить, есть ли способ открыть лист с новым NavigationStack в iOS 16, но не могу найти способ.
Таким образом, можно открыть лист, используя:
.sheet(isPresented: $isShowing)
Но с новым NavigationStack у вас есть массив типа, который вы представляете:
.navigationDestination(for: SomeType.self, destination: { route in
И было бы здорово, если бы я мог каким-то образом определить, что при представлении определенного пункта назначения он открывается как лист, а не в модальном окне.
Кто-нибудь знает, возможно ли это достичь? :)
2 ответа
Мне до сих пор не удалось найти чистое решение для этого, используя только NavigationDestination, однако в итоге я реализовал что-то вроде этого, что делает это возможным.
Я решил, что на данный момент опубликую это как ответ, поскольку кто-то, возможно, сможет улучшить это еще больше или сделать его более общим.
enum Route: Hashable, Identifiable {
var id: Self { return self }
case details(RouteType)
case shopping(RouteType)
}
enum RouteType {
case modal
case sheet
}
struct ContentView: View {
@State private var path = NavigationPath()
@State private var route: Route?
@State private var sheet: Route?
func router(_ route: Route, type: RouteType) {
switch type {
case .modal:
path.append(route)
case .sheet:
sheet = route
}
}
func getView(for route: Route) -> some View {
switch route {
case .details(_):
return Text("Details View")
case .shopping(_):
return Text("Shopping View")
}
}
var body: some View {
NavigationStack(path: $path) {
VStack {
Text("Content View")
Button("Show View") {
route = Route.details(.sheet) // <- Change accordingly
}
}
.navigationTitle("Content View")
.onChange(of: route) { newRoute in
guard let newRoute else { return }
switch newRoute {
case .details(let type):
router(newRoute, type: type)
case .shopping(let type):
router(newRoute, type: type)
}
route = nil
}
.navigationDestination(for: Route.self) { route in
getView(for: route)
}
.sheet(item: $sheet) { route in
getView(for: route)
}
}
}
}
Это сработало для меня. Я могу подталкивать объекты к моему маршруту из любого представления и загружать его с помощью модального листа.
class Route: ObservableObject {
@Published var presentedObject: [CarObject] = []
@Published var isPresented: Bool = false
}
struct NavigationWithSheet: View {
var body: some View {
@EnvironmentObject var route: Route
NavigationStack {
Button("Open sheet") {
route.isPresented = true
route.presentedObject.append(newCar)
}
.sheet(isPresented: $route.isPresented) {
let carObject = route.presentedObject.first
ViewWithObject(car: carObject!)
}
}
}
}