1

I'm using a three column navigation layout and facing the issue, that when selecting the same second column's item, the drawers won't close. If I take the files app as reference, selecting the same item again will close the drawer. Can someone tell me what's the issue? And is drawer the correct term?

Code to reproduce:

import SwiftUI

extension UISplitViewController {

    open override func viewDidLoad() {
        preferredDisplayMode = .twoBesideSecondary
    }
}

@main
struct TestApp: App {

    @Environment(\.factory) var factory

    var body: some Scene {
        WindowGroup {
            NavigationView {
                ContentView(viewModel: factory.createVM1())
                ContentView2(viewModel: factory.createVM2())
                EmptyView()
            }
        }
    }
}

struct FactoryKey: EnvironmentKey {
    static let defaultValue: Factory = Factory()
}

extension EnvironmentValues {

    var factory: Factory {
        get {
            return self[FactoryKey.self]
        }
        set {
            self[FactoryKey.self] = newValue
        }
    }
}

class Factory {
    func createVM1() -> ViewModel1 {
        ViewModel1()
    }

    func createVM2() -> ViewModel2 {
        ViewModel2()
    }

    func createVM3(from item: ViewModel2.Model) -> ViewModel3 {
        ViewModel3(item: item)
    }
}

class ViewModel1: ObservableObject {

    struct Model: Identifiable {
        let id: UUID = UUID()
        let name: String
    }

    @Published var items: [Model]

    init() {
        items = (1 ... 4).map { Model(name: "First Column Item \($0)") }
    }
}

struct ContentView: View {
    @Environment(\.factory) var factory

    @StateObject var viewModel: ViewModel1

    var body: some View {
        List {
            ForEach(viewModel.items) { item in
                NavigationLink(
                    destination: ContentView2(viewModel: factory.createVM2()),
                    label: {
                        Text(item.name)
                    })
            }
        }
    }
}

class ViewModel2: ObservableObject {

    struct Model: Identifiable {
        let id: UUID = UUID()
        let name: String
    }

    @Published var items: [Model]

    init() {
        items = (1 ... 4).map { Model(name: "Second Column Item \($0)") }
    }
}

struct ContentView2: View {

    @Environment(\.factory) var factory
    @StateObject var viewModel: ViewModel2

    var body: some View {

        List {
            ForEach(viewModel.items) { item in
                NavigationLink(
                    destination: Detail(viewModel: factory.createVM3(from: item)),
                    label: {
                        Text(item.name)
                    })
            }
        }
    }
}

class ViewModel3: ObservableObject {
    let item: ViewModel2.Model

    init(item: ViewModel2.Model) {
        self.item = item
    }
}

struct Detail: View {

    @StateObject var viewModel: ViewModel3

    var body: some View {
        Text(viewModel.item.name)
    }
}

Carsten
  • 581
  • 4
  • 17

0 Answers0