Вот код, который я создал для создания макета, который вы ищете в 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.")
}
}
}
}