SwiftUI - 使工具栏的 NavigationLink 使用详细视图

Posted

技术标签:

【中文标题】SwiftUI - 使工具栏的 NavigationLink 使用详细视图【英文标题】:SwiftUI - Make toolbar's NavigationLink use detail view 【发布时间】: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() 完美运行! 【参考方案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()

以上是关于SwiftUI - 使工具栏的 NavigationLink 使用详细视图的主要内容,如果未能解决你的问题,请参考以下文章

带有 SidebarListStyle 的 SwiftUI 列表没有圆角?

SwiftUI:使插入列表背景透明?

如何使用 SwiftUI 使这个 ForEach 函数工作?

需要帮助使 NavigationLink 在 SwiftUI 中工作

SwiftUI:如何使列表视图透明?如何更改列表视图背景颜色?

SwiftUI - 使列表分隔线扩展到触摸屏边缘