【问题标题】:SwiftUI - Make toolbar's NavigationLink use detail viewSwiftUI - 使工具栏的 NavigationLink 使用详细视图
【发布时间】:2021-10-21 14:41:40
【问题描述】:

我正在开发一个两窗格的 SwiftUI 应用程序,在 DoubleColumnNavigationView 中带有侧边栏和详细信息窗格。

我想从侧边栏的工具栏中打开一个NavigationLink 到详细信息窗格中,如下图 gif 中的“从侧边栏打开”所示)。

但是,视图以堆栈的形式打开,如下图 gif 中的“从工具栏打开”所示。

使用isDetailLink(true) 似乎没有效果。

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: Text("Opened from sidebar")) {
                    Text("Open from sidebar")
                }
            }.listStyle(SidebarListStyle())
            .navigationTitle("Sidebar")
            .toolbar {
                ToolbarItem {
                    // This should open in detail pane
                    NavigationLink(destination: Text("Opened from toolbar")) {
                        Text("Open from toolbar")
                    }
                }
            }
            Text("Detail pane")
        }.navigationViewStyle(DoubleColumnNavigationViewStyle())
    }
}

【问题讨论】:

  • 将链接放入列表中。隐藏它并使用 isActive @State 将其切换为活动状态
  • @loremipsum 我还没有找到隐藏List 行的简单方法。使用if 语句意味着每次切换时都需要重新加载目标。
  • 不是if 只是.hidden() 并在初始化程序中使用NavigationLinkisActive。然后你只需切换@State
  • .hidden() 隐藏行内容,而不是行本身。无论如何,Denis's answer using .background() 完美运行!

标签: swift swiftui navigationview swiftui-navigationlink swiftui-navigationview


【解决方案1】:

通用解决方案

您可能知道,NavigationLink 在放入 toolbar 时效果不佳。这里建议 - 将Button 放入toolbar 并在代码中的某处使用隐藏的NavigationLink。该按钮告诉链接打开详细视图并且链接执行操作。这是根据此建议调整的代码:

struct ContentView: View {
    /// A state that tracks whether the link in the toolbar should be opened
    @State var toolbarLinkSelected = false
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: Text("Opened from sidebar")) {
                    Text("Open from sidebar")
                }
            }.listStyle(SidebarListStyle())
            .navigationTitle("Sidebar")
            .toolbar {
                ToolbarItem {
                    Button(action: { toolbarLinkSelected = true }) {
                        Text("Open from toolbar")
                    }
                }
            }
            .background(
                NavigationLink(
                    destination: Text("Opened from toolbar"),
                    isActive: $toolbarLinkSelected
                ) {
                    EmptyView()
                }.hidden() // The link is not visible to user
            )
            Text("Detail pane")
        }.navigationViewStyle(DoubleColumnNavigationViewStyle())
    }
}

iOS / iPadOS 唯一解决方案

另外,如果您只需要支持 iOS 和 iPadOS,您可以使用旧的方式来实现它,使用 navigationBarItems。这不适用于 macOS,因为此修饰符不可用,但适用于 iOS/iPadOS。示例如下:

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: Text("Opened from sidebar")) {
                    Text("Open from sidebar")
                }
            }.listStyle(SidebarListStyle())
            .navigationTitle("Sidebar")
            .navigationBarItems(trailing: NavigationLink(destination: Text("Opened from toolbar")) {
                Text("Open from toolbar")
            })
            Text("Detail pane")
        }.navigationViewStyle(DoubleColumnNavigationViewStyle())
    }
}

【讨论】:

  • 这是一个绝妙的解决方案!我没有考虑过.background()
猜你喜欢
  • 1970-01-01
  • 2021-01-07
  • 1970-01-01
  • 2011-07-16
  • 2020-09-10
  • 2021-12-12
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多