【问题标题】:How do I handle selection in NavigationView on macOS correctly?如何正确处理 macOS 上 NavigationView 中的选择?
【发布时间】:2020-04-30 14:08:47
【问题描述】:

我想根据侧边栏中的选择构建一个带有侧边栏和一些内容的简单 macOS 应用程序。

我有一个 MainView,其中包含一个 NavigationView 和一个 SidebarListStyle。它包含一个List 和一些NavigationLinks。这些具有选择绑定。

我希望以下事情能够奏效:

  1. 当我启动我的应用程序时,选择的值被忽略。侧边栏中的项目都没有突出显示,详细信息窗格中也没有内容。

  2. 当我在边栏中手动选择一个项目时,应该可以通过项目之间的向上/向下箭头键进行导航。这不起作用,因为选择/突出显示消失了。

  3. 当我更新选择绑定的值时,它应该突出显示列表中没有发生的项目。

这是我的示例实现:

enum DetailContent: Int, CaseIterable {
    case first, second, third
}
extension DetailContent: Identifiable {
    var id: Int { rawValue }
}

class NavigationRouter: ObservableObject {
    @Published var selection: DetailContent?
}

struct DetailView: View {
    @State var content: DetailContent
    @EnvironmentObject var navigationRouter: NavigationRouter

    var body: some View {
        VStack {
            Text("\(content.rawValue)")
            Button(action: { self.navigationRouter.selection = DetailContent.allCases.randomElement()!}) {
                Text("Take me anywhere")
            }
        }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

struct MainView: View {
    @ObservedObject var navigationRouter = NavigationRouter()
    @State var detailContent: DetailContent? = .first

    var body: some View {
        NavigationView {
            List {
                Section(header: Text("Section")) {
                    ForEach(DetailContent.allCases) { item in
                        NavigationLink(
                            destination: DetailView(content: item),
                            tag: item,
                            selection: self.$detailContent,
                            label: { Text("\(item.rawValue)") }
                        )
                    }
                }
            }
            .frame(minWidth: 250, maxWidth: 350)
        }
            .environmentObject(navigationRouter)
            .listStyle(SidebarListStyle())
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .onReceive(navigationRouter.$selection) { output in
                self.detailContent = output
            }
    }
}

EnvironmentObject 用于从DetailView 内部传播更改。如果有更好的解决方案,我很高兴听到。

所以问题仍然存在: 发生这种情况我做错了什么? 我曾希望使用 Xcode 11.5 Beta 1 这会消失,但事实并非如此。

【问题讨论】:

    标签: swift macos swiftui swiftui-navigationlink


    【解决方案1】:

    在找到tutorial from Apple 后,很明显您没有在 macOS 上使用NavigiationLink。相反,您绑定列表并将两个视图添加到NavigationView

    通过对MainViewDetailView 的这些更新,我的示例完美运行:

    struct DetailView: View {
        @Binding var content: DetailContent?
        @EnvironmentObject var navigationRouter: NavigationRouter
    
        var body: some View {
            VStack {
                Text("\(content?.rawValue ?? -1)")
                Button(action: { self.navigationRouter.selection = DetailContent.allCases.randomElement()!}) {
                    Text("Take me anywhere")
                }
            }
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
    
    struct MainView: View {
        @ObservedObject var navigationRouter = NavigationRouter()
        @State var detailContent: DetailContent?
    
        var body: some View {
            NavigationView {
                List(selection: $detailContent) {
                    Section(header: Text("Section")) {
                        ForEach(DetailContent.allCases) { item in
                            Text("\(item.rawValue)")
                                .tag(item)
                        }
                    }
                }
                    .frame(minWidth: 250, maxWidth: 350)
                    .listStyle(SidebarListStyle())
                DetailView(content: $detailContent)
            }
                .environmentObject(navigationRouter)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .onReceive(navigationRouter.$selection) { output in
                    DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(200)) {
                        self.detailContent = output
                    }
                }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      • 2019-10-30
      相关资源
      最近更新 更多