SwiftUI - 使工具栏的 NavigationLink 使用详细视图
SwiftUI - Make toolbar's NavigationLink use detail view
我正在开发一个双面板 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())
}
}
通用解决方案
如您所知,NavigationLink
放在 toolbar
中效果不佳。这里的建议是将 Button
放入 toolbar
并在代码中的某处使用隐藏的 NavigationLink
。该按钮告诉 link 打开详细视图,然后 link 执行操作。这是根据此建议调整的代码:
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())
}
}
我正在开发一个双面板 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())
}
}
通用解决方案
如您所知,NavigationLink
放在 toolbar
中效果不佳。这里的建议是将 Button
放入 toolbar
并在代码中的某处使用隐藏的 NavigationLink
。该按钮告诉 link 打开详细视图,然后 link 执行操作。这是根据此建议调整的代码:
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())
}
}