В NavigationStack отсутствует корневой контроллер из пути

я создаю историческую навигацию (назад, вперед) для приложения macOS

В основном это работает нормально, но моя реализация зависит от пути, который, однако, не содержит корня (когда выбрана боковая панель, а [] назначается пути)

как получить рут, или сохранить рут отnavigationDestination

      import SwiftUI

enum NavigationDestination: Hashable {
    
    case test1
    case test2
    case test3(text:String)

}

struct SidebarView: View {
    var body: some View {
        VStack {
            
            NavigationLink(value: NavigationDestination.test1) {
                Text("1")
            }
            NavigationLink(value: NavigationDestination.test2) {
                Text("2")
            }
            NavigationLink(value: NavigationDestination.test3(text:"X")) {
                Text("3")
            }
            
        }
    }
}

struct TestView: View {
    
    let text: String
    
    var body: some View {
        VStack {
            Text(text)
            NavigationLink(value: NavigationDestination.test1) {
                Text("1")
            }
            NavigationLink(value: NavigationDestination.test2) {
                Text("2")
            }
            NavigationLink(value: NavigationDestination.test3(text:"3-1")) {
                Text("3-1")
            }
            NavigationLink(value: NavigationDestination.test3(text:"3-2")) {
                Text("3-2")
            }
            NavigationLink(value: NavigationDestination.test3(text:"3-3")) {
                Text("3-3")
            }
            NavigationLink(value: NavigationDestination.test3(text:"3-4")) {
                Text("3-4")
            }
            NavigationLink(value: NavigationDestination.test3(text:"3-5")) {
                Text("3-5")
            }
            List {
                ForEach(0..<200) { index in
                    Text("LIST \(index)")
                }
            }
        }
    }
    
}

struct MainView: View {
    
    @State private var history: [[NavigationDestination]] = []
    @State private var historyIndex: Int = -1
    @State private var canGoBackInHistory = false
    @State private var canGoForwardInHistory = false
    
    @State private var path: [NavigationDestination] = []

    var body: some View {
        NavigationSplitView(columnVisibility: .constant(.all)) {
            SidebarView()
                .navigationDestination(for: NavigationDestination.self) { destination in
                    detailBuilder(destination)
                        .navigationBarBackButtonHidden(true)
                }
        } detail: {
            NavigationStack(path: $path) {
                Group {
                }
                .navigationDestination(for: NavigationDestination.self) { destination in
                    detailBuilder(destination)
                        .navigationBarBackButtonHidden(true)
                }
            }
            
        }
        .onChange(of: path) { newValue in
            if history[safe: historyIndex] == newValue {
                return
            }
            if historyIndex != history.count - 1 {
                history.removeLast(history.count - historyIndex)
            }
            if newValue != [] {
                history.append(newValue)
            }
            historyIndex = history.count - 1
            canGoBackInHistory = history.count > 0
            canGoForwardInHistory = false
            print("======\n \(history)")
        }
        .toolbar {
            ToolbarItemGroup(placement: .navigation) {
                Button(action: {
                    goBackInHistory()
                }, label: {
                    Image(systemName: "chevron.left")
                })
                .disabled(!canGoBackInHistory)
                Button(action: {
                    goForwardInHistory()
                }, label: {
                    Image(systemName: "chevron.right")
                })
                .disabled(!canGoForwardInHistory)
                
            }
        }
    }
    
    func goBackInHistory() {
        guard let h = history[safe: historyIndex - 1] else {
            return
        }
        historyIndex -= 1
        
        canGoBackInHistory = historyIndex > 0
        canGoForwardInHistory = true
        
        withAnimation {
            path = h
        }
    }

    func goForwardInHistory() {
        guard let h = history[safe: historyIndex + 1] else {
            return
        }
        historyIndex += 1
        
        canGoBackInHistory = true
        canGoForwardInHistory = historyIndex < (history.count - 1)
        
        withAnimation {
            path = h
        }
    }
    
    @ViewBuilder
    func detailBuilder(_ destination: NavigationDestination) -> some View {
        switch destination {
        case .test1:
            TestView(text: "1")
        case .test2:
            TestView(text: "2")
        case .test3(let text):
            TestView(text: text)
        }
    }
    
}

struct MainView_Previews: PreviewProvider {
    static var previews: some View {
        MainView()
    }
}

extension Collection where Indices.Iterator.Element == Index {

    /// Returns the element at the specified index if it is within bounds, otherwise nil.
    subscript (safe index: Index) -> Iterator.Element? {
        return indices.contains(index) ? self[index] : nil
    }

}

0 ответов

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