问题描述
我正在尝试将不同的toolbar
添加到我的每个选项卡中,但它们没有显示。该应用程序将主要在横向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
。换句话说,您不应该嵌套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%ssolution。