SwiftUI 自定义标签栏导航:当图标被标签化时返回到根视图

时间:2021-04-29 11:40:05

标签: swiftui

我按照本教程在我的 SwiftUI 应用程序中创建了一个自定义标签栏:https://blckbirds.com/post/custom-tab-bar-in-swiftui/

我想实现这一点,当您选择一个图标时,您将始终被移动到该选项卡视图中 NavigationView 的“RootView”。例如,在 HomeView 上,我有一个带有嵌套视图的 NavigationView。因此,当您导航到 DetailView1 -> DetailView2 然后再次点击主页图标时,您将返回到初始视图。

对于自定义导航,我有一个 ViewRouter.swift

ViewRouter.swift

class ViewRouter: ObservableObject {
    @Published var currentPage: Page = .home
}

enum Page {
    case home
    case liked
    case add
    case records
    case user
}

在我的 ContentView 中

struct ContentView: View {
    @StateObject var viewRouter: ViewRouter
    
    var body: some View {
        GeometryReader { geometry in
            VStack {
                Spacer()
                switch viewRouter.currentPage {
                case .home:
                    HomeView()
                case .liked:
                    LikedView()
                case .add:
                    AddView()
                case .records:
                    RecordsView()
                case .user:
                    UserView()
                }
                Spacer()
                HStack {
                    TabBarIcon(viewRouter: viewRouter, assignedPage: .home, width: geometry.size.width/5, height: geometry.size.height/28, systemIconName: "homekit", tabName: "Home")
                    TabBarIcon(viewRouter: viewRouter, assignedPage: .liked, width: geometry.size.width/5, height: geometry.size.height/28, systemIconName: "heart", tabName: "Liked")
                    TabBarIcon(viewRouter: viewRouter, assignedPage: .records, width: geometry.size.width/5, height: geometry.size.height/28, systemIconName: "waveform", tabName: "Records")
                    TabBarIcon(viewRouter: viewRouter, assignedPage: .user, width: geometry.size.width/5, height: geometry.size.height/28, systemIconName: "person.crop.circle", tabName: "Account")
                }
                .frame(width: geometry.size.width, height: geometry.size.height/8)
                .background(Color("TabBarBackground"))
                .shadow(radius: 2)
            }
            .edgesIgnoringSafeArea(.all)
        }
    }
}

struct TabBarIcon: View {
    @StateObject var viewRouter: ViewRouter
    var assignedPage: Page
    
    let width, height: CGFloat
    let systemIconName, tabName: String
    
    var body: some View {
        VStack {
            Image(systemName: systemIconName)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: width, height: height)
                .padding(.top, 10)
            Text(tabName)
                .font(.footnote)
            Spacer()
        }
        .padding(.horizontal, -4)
        .onTapGesture {
            viewRouter.currentPage = assignedPage
        }
        .foregroundColor(viewRouter.currentPage == assignedPage ? Color("TabBarHighlight") : .gray)
    }
}

然后在我的 HomeView 中作为示例,一个具有多个级别的 NavigationView。导航工作正常,而且当您在另一个选项卡和主页上的选项卡上时,您总是会进入此导航堆栈的第一个视图,这是完美的。所以当你在 Home 的 NavigationView 中时,我想实现同样的事情,有点像重置 NavigationStack。

有什么想法吗?

0 个答案:

没有答案