如何使用 SwiftUI 从另一个 TabBarView 触发 TabBar 视图

How to trigger a TabBar View from another TabBarView with SwiftUI

在 SwiftUI 中,我创建了一个简单的基于标签栏的视图:

struct ContentView: View {
    enum Tab: Int {
        case menu, news, viewc, viewd, viewf
    }
    @State var selectedTab = Tab.menu

    func tabbarItem(text: String, image: String) -> some View {
        VStack {
            Image(systemName: image)
                .imageScale(.large)
            Text(text)
        }
    }

    var body: some View {
         TabView(selection: $selectedTab) {
                     MenuView().tabItem{
                         self.tabbarItem(text: "Menu", image: "list.dash")
                     }.tag(Tab.menu)
                     NewsView().tabItem{
                         self.tabbarItem(text: "News", image: "doc")
                     }.tag(Tab.news)
                     EmptyView().tabItem{
                         self.tabbarItem(text: "ViewC", image: "star.circle")
                     }.tag(Tab.viewc)
                     EmptyView().tabItem{
                         self.tabbarItem(text: "ViewD", image: "speaker")
                     }.tag(Tab.viewd)
                     EmptyView().tabItem{
                         self.tabbarItem(text: "ViewF", image: "person")
                     }.tag(Tab.viewf)
         }
    }
}

如下图所示:

Questions:

提前致谢。

这是我为实现您在 Swift 中寻找的布局而创建的代码UI。希望这有帮助。

import SwiftUI

struct ContentView: View {
    enum Tab: Int {
        case menu, news, viewc, viewd, viewf
    }
    @State var selectedTab = Tab.menu
    @State var showFilter: Bool = false
    @State var selectedFilter: String = ""

    func tabbarItem(text: String, image: String) -> some View {
        VStack {
            Image(systemName: image)
                .imageScale(.large)
            Text(text)
        }
    }

    var body: some View {
        TabView(selection: $selectedTab) {
            NavigationView {
                NewsView(filter: $selectedFilter)
                .navigationBarItems(trailing: Button(action: { self.showFilter.toggle() }) {
                    Text("Filters")
                })
                .navigationBarTitle("News")
                .sheet(isPresented: $showFilter) {
                    MenuView(selectedFilter: self.$selectedFilter)
                }
            }
            .tabItem{
                self.tabbarItem(text: "News", image: "doc")
            }
            .tag(Tab.news)

            ViewC().tabItem{
                self.tabbarItem(text: "ViewC", image: "star.circle")
            }.tag(Tab.viewc)
            EmptyView().tabItem{
                self.tabbarItem(text: "ViewD", image: "speaker")
            }.tag(Tab.viewd)
            EmptyView().tabItem{
                self.tabbarItem(text: "ViewF", image: "person")
            }.tag(Tab.viewf)
        }
    }
}

struct MenuView: View {
    @Environment(\.presentationMode) var presentationMode
    var menus: [String] = ["Menu No.1", "Menu No.2", "Menu No.3"]
    @Binding var selectedFilter: String
    var body: some View {
        List {
            ForEach(menus, id: \.self) { menu in
                Button(action: {
                    self.selectedFilter = menu
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Text("\(menu)")
                }
            }
        }
    }
}

struct NewsView: View {
    @Binding var filter: String

    var body: some View {
        List {
            if filter.count > 0 {
                Text("The news is filtered using \(filter)")
            }
            else {
                Text("The latest news is being displayed.")
            }
        }
    }
}

struct ViewC: View {
    var body: some View {
        Text("Under construction")
    }
}

上一个答案

要实现当前布局,您需要在 NavigationView 中嵌套 TabView。我创建了一个示例项目来测试它,下面是代码。虽然它有效,但在单击后退按钮时,我收到了以下警告:

"Trying to pop to a missing destination at /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.4.3/UIKit/UIKitNavigationBridge.swift:390"

因此,您可能需要重新考虑该应用程序 UI。由于菜单选项卡只是新闻选项卡的过滤器,因此有一个将菜单和新闻选项卡合二为一的 TabView。启动时,该应用程序将显示最新消息。然后,您可以在 NewsView 中为过滤器创建一个单独的视图。

import SwiftUI

struct ContentView: View {
    enum Tab: Int {
        case menu, news, viewc, viewd, viewf
    }
    @State var selectedTab = Tab.menu

    func tabbarItem(text: String, image: String) -> some View {
        VStack {
            Image(systemName: image)
                .imageScale(.large)
            Text(text)
        }
    }

    var body: some View {
        NavigationView {
            TabView(selection: $selectedTab) {
                MenuView().tabItem{
                    self.tabbarItem(text: "Menu", image: "list.dash")
                }.tag(Tab.menu)
                NewsView().tabItem{
                    self.tabbarItem(text: "News", image: "doc")
                }.tag(Tab.news)
                EmptyView().tabItem{
                    self.tabbarItem(text: "ViewC", image: "star.circle")
                }.tag(Tab.viewc)
                EmptyView().tabItem{
                    self.tabbarItem(text: "ViewD", image: "speaker")
                }.tag(Tab.viewd)
                EmptyView().tabItem{
                    self.tabbarItem(text: "ViewF", image: "person")
                }.tag(Tab.viewf)
            }
        }
    }
}

struct MenuView: View {
    var menus: [String] = ["Menu No.1", "Menu No.2", "Menu No.3"]
    var body: some View {
        List {
            ForEach(menus, id: \.self) { menu in
                NavigationLink(destination: NewsView(filter: "filterString")) {
                    Text("\(menu)")
                }
            }
        }
    }
}

struct NewsView: View {
    var filter: String = ""

    var body: some View {
        List {
            if filter.count > 0 {
                Text("The news is filtered using \(filter)")
            }
            else {
                Text("The latest news is being displayed.")
            }
        }
    }
}