Как вызвать TabBar View из другого TabBarView с помощью SwiftUI - PullRequest
0 голосов
/ 16 марта 2020

В 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)
         }
    }
}

Как на экране, показанном ниже:

Tab1 Tab2

Вопросы:

  • Как мне реализовать то, что мне нужно в SwiftUI?

  • Использую ли я соответствующие компоненты для этого? По сути, это меню и список, если вкладка новости, он просто загрузит последние новости, если щелкнуть из меню, он отобразит отфильтрованные новости.

Заранее спасибо ,

1 Ответ

1 голос
/ 16 марта 2020

Вот код, который я создал для создания макета, который вы ищете в SwiftUI. Надеюсь, это поможет.

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")
    }
}

ПРЕДЫДУЩИЙ ОТВЕТ

Чтобы получить текущий макет, вам нужно вложить TabView внутри NavigationView. Я создал пример проекта, чтобы проверить это, и ниже приведен код. Хотя это работает, при нажатии кнопки «Назад» я получил следующее предупреждение:

«Попытка всплыть на отсутствующий пункт назначения в /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros_Sim/Monoceros-39.4 .3 / UIKit / UIKitNavigationBridge.swift: 390 "

Поэтому вам может потребоваться переосмыслить пользовательский интерфейс приложения. Поскольку вкладка меню представляет собой только фильтры для вкладки «Новости», имейте 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.")
            }
        }
    }
}
...