SwiftUI - 如何将工具栏添加到 NavigationView 内的 TabView 选项卡?
Posted
技术标签:
【中文标题】SwiftUI - 如何将工具栏添加到 NavigationView 内的 TabView 选项卡?【英文标题】:SwiftUI - How to add toolbars to TabView tabs inside a NavigationView? 【发布时间】:2021-09-13 10:58:26 【问题描述】:我正在尝试将不同的toolbar
s 添加到我的每个选项卡,但它们没有显示。该应用程序将主要在横向 iPad 上使用,我可以将工具栏添加到 TabView
本身并显示它们,但是我不知道如何将按钮按下导航堆栈传递给各个视图/视图模型本地处理。
我尝试添加新的NavigationView
s(包括.stack
navigationViewStyle
s),但这仍然只是在视图中添加了另一列。
这是一些准系统,工作代码:
import SwiftUI
@main
struct NavTabTestApp: App
var body: some Scene
WindowGroup
ContentView()
struct ContentView: View
var body: some View
MasterView()
struct MasterView: View
var body: some View
NavigationView
List
ForEach(0..<20) index in
NavigationLink(
destination: DetailView(index: index)
.navigationTitle("Row \(index)")
)
Text("\(index) th row")
.tag(index)
.navigationTitle(Text("Ratty"))
struct DetailView: View
var index: Int
@State var selectedTab = 1
var body: some View
TabView(selection: $selectedTab)
Tab1(index: index).tabItem Label("Tab1", systemImage: "list.dash")
Tab2(index: index).tabItem Label("Tab2", systemImage: "aqi.medium")
Tab3(index: index).tabItem Label("Tab3", systemImage: "move.3d")
struct Tab1: View
var index: Int
var body: some View
Text("This is \(index) in tab 1")
.toolbar
ToolbarItem(placement: .primaryAction)
Button("Bingo") print("Bingo")
struct Tab2: View
var index: Int
var body: some View
Text("This is \(index) in tab 2")
.toolbar
ToolbarItem(placement: .primaryAction)
Button("Bongo") print("Bongo")
struct Tab3: View
var index: Int
var body: some View
Text("This is \(index) in tab 3")
.toolbar
ToolbarItem(placement: .primaryAction)
Button("Banjo") print("Banjo")
我开始怀疑这是否可能,以及在每个选项卡顶部使用按钮实现我自己的视图是否会更好。
编辑:
【问题讨论】:
NavigationView 应该是 TabView 的子项,而不是您所做的其他方式。导航到 DetailsView 是否重要?您可以呈现它并为每个选项卡视图添加一个 NavgationView? @mahan - 我尝试将 NavigationView 移动到 List 中,但我的视图变得毫无意义。我不明白我可以把它放在哪里。另外,我没有绑定到 NavigationLink,但是当从列表中选择某些内容时,我将如何填充 Detail 视图? 【参考方案1】:不确定这是否有帮助,但它确实通过导航视图中的工具栏回顾了一些有趣的概念。
链接:Stewart Lynch
【讨论】:
谢谢。有趣的东西,但我认为我的问题与 TabViews 处理/继承 NavigationViews 的特定方式有关。【参考方案2】:您只需要使用一级NavigationView
。换句话说,你不应该嵌套NavigationViews
。看看这个答案。
Only Back Button Visible on Custom Navigation Bar SwiftUI
-
将
NavgationView
用作您所使用的MasterView
。
为每个Tab#
视图使用NavigationView
。
在MasterView
和DetailsView
之间切换。
在MasterView
中使用Button
而不是NavigationLink
(您可以将其自定义为NavigationLink
)
在每个Tab#
视图中使用自定义后退按钮。
这控制应该显示MasterView
和DetailsView
中的哪一个。
class BaseViewModel: ObservableObject
@Published var userFlow: UserFlow = .masterView
init()
userFlow = .masterView
enum UserFlow
case masterView, detailsView
此视图可用于ContentView
或代替它。当您在MasterView
中并单击列表行之一时,设置appState.userFlow = .detailView
。单击后退按钮时,设置appState.userFlow = .masterView
。
这样做,您在两个视图之间切换,一次显示一个NavigationView
。
截至目前,它没有动画。如果您愿意,请使用
https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions
struct BaseView: View
@EnvironmentObject var appState: BaseViewModel
@State var index: Int = 0
var body: some View
Group
switch appState.userFlow
case .masterView:
MasterView(index: $index)
default:
DetailView(index: index)
.edgesIgnoringSafeArea(.bottom)
完整代码
struct ContentView: View
var body: some View
BaseView().environmentObject(BaseViewModel())
class BaseViewModel: ObservableObject
@Published var userFlow: UserFlow = .masterView
init()
userFlow = .masterView
enum UserFlow
case masterView, detailsView
struct BaseView: View
@EnvironmentObject var appState: BaseViewModel
@State var index: Int = 0
var body: some View
Group
switch appState.userFlow
case .masterView:
MasterView(index: $index)
default:
DetailView(index: index)
.edgesIgnoringSafeArea(.bottom)
struct MasterView: View
@EnvironmentObject var appState: BaseViewModel
@Binding var index: Int
var body: some View
NavigationView
List
ForEach(0..<20) index in
Button(action:
appState.userFlow = .detailsView
$index.wrappedValue = index
, label:
HStack
Text("\(index) th row")
Spacer()
Image(systemName: "greaterthan")
)
.tag(index)
.navigationTitle(Text("Ratty"))
struct DetailView: View
var index: Int
@State var selectedTab = 1
var body: some View
TabView(selection: $selectedTab)
Tab1(index: index).tabItem Label("Tab1", systemImage: "list.dash")
Tab2(index: index).tabItem Label("Tab2", systemImage: "aqi.medium")
Tab3(index: index).tabItem Label("Tab3", systemImage: "move.3d")
struct Tab1: View
@EnvironmentObject var appState: BaseViewModel
var index: Int
var body: some View
NavigationView
Text("This is \(index) in tab 1")
.toolbar
ToolbarItem(placement: .navigationBarLeading)
Button("back") appState.userFlow = .masterView
ToolbarItem(placement: .navigationBarTrailing)
Button("Bingo") print("Bingo")
struct Tab2: View
@EnvironmentObject var appState: BaseViewModel
var index: Int
var body: some View
NavigationView
Text("This is \(index) in tab 2")
.toolbar
ToolbarItem(placement: .navigationBarLeading)
Button("back") appState.userFlow = .masterView
ToolbarItem(placement: .primaryAction)
Button("Bongo") print("Bongo")
struct Tab3: View
@EnvironmentObject var appState: BaseViewModel
var index: Int
var body: some View
NavigationView
Text("This is \(index) in tab 3")
.toolbar
ToolbarItem(placement: .navigationBarLeading)
Button("back") appState.userFlow = .masterView
ToolbarItem(placement: .primaryAction)
Button("Banjo") print("Banjo")
我已经自定义了xtwistedx 的solution。
【讨论】:
谢谢!这看起来很有希望,我明天会完成它。但是,不同的工具栏出现在主(列表)视图中,而不是单个详细信息/选项卡视图中。我会看看我是否可以使用你的代码来实现这一点,然后我会相信你的回答。 不,工具栏已附加到选项卡视图。 @Magnas 是的,工具栏附加到代码中的选项卡视图,但工具栏附加到主(左)视图,我希望不同的工具栏附加到细节(右)意见。请查看我对问题的编辑。 @Magnas 选项卡视图是否有导航项(标题、按钮等)?以上是关于SwiftUI - 如何将工具栏添加到 NavigationView 内的 TabView 选项卡?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 SwiftUI 向 macOS 应用程序添加工具栏?
如何使用 SwiftUI 将上下文菜单添加到 NavigationLink?
如何将我的自定义 ButtonStyle 添加到 swiftui3 中的快捷方式 swiftui .buttonstyle() 属性