Представление листа с помощью 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!)
            }
        }
        
    }
}

Другие вопросы по тегам