美文网首页
SwiftUI 路由管理 NavigationStack

SwiftUI 路由管理 NavigationStack

作者: 激动的厨师 | 来源:发表于2023-03-10 11:43 被阅读0次

因为对moya框架的使用,给了我启发,花点时间封装了下 NavigationStack 的路由管理。不多说,上代码:

先定义个Path的枚举,对应APP的每个页面,可带参数(moya的API也是这样处理的)
enum SFNavigationPath:Hashable{
    
    case loginPath
    case baseTabbarPath
    
    case baoBiaoPath
    
    
    case yewuPath
    
    
    case homePath
    
    case customersPath
    case customerDetailPath
    case customerAddOrEidtPath
    
    case newsPath
    case newsDetailPath
    case newsListPath
    
    
    case testPath(_ index:Int)//带参数类型测试
    case testPath2
    
    
    func pageParamView() -> some View{
        switch self {
        case .loginPath:
            return AnyView(LoginView())
        case .baseTabbarPath:
            return AnyView(BaseTabbar())
        case .baoBiaoPath:
            return AnyView(BaoBiaoView())
        case .yewuPath:
            return AnyView(YewuView())
        case .homePath:
            return AnyView(HomeSpace())
        case .customersPath:
            return AnyView(CustomersView())
        case .newsPath:
            return AnyView(NewsView())
        case .testPath(let index):
            return AnyView(TestPage(index: index))
        case .testPath2:
            return AnyView(TestPage2())
        default:
            return AnyView(TestPage2())
        }
    }
}

再定义一个SFNavigationDelegate 协议代理,协议方法 有push...等这些一看就懂。
protocol SFNavigationDelegate{
    associatedtype Route = SFNavigationPath
    func push(_ path:Route)
    func pop()
    func popToRoot()
    func popUntil(_ path:Route)
}

继续做一个View分类用来 导航页面用,具体就是用到的时候,需要实现调用,当然也可以自己实现navigationDestination,具体看业务需求吧。
extension View{
    //返回默认,或者简单参数的页面
    func pathNormalPageView() -> some View {
        self.navigationDestination(for: SFNavigationPath.self) { path in
            path.pageParamView()
        }
    }
    
    //如果复杂参数,可以用这个
    func pathCustPageView(@ViewBuilder destination: @escaping (_ path:SFNavigationPath) -> some View) -> some View{
        self.navigationDestination(for: SFNavigationPath.self, destination: destination)
    }
}

最后写一个manger 遵守协议来管理导航


class PathManager:ObservableObject,SFNavigationDelegate{
    @Published var manager:[SFNavigationPath] = []
    
    func push(_ path: SFNavigationPath) {
        self.manager.append(path)
    }
    
    func pop() {
        self.manager.removeLast()
    }
    
    func popToRoot() {
        self.manager.removeAll()
    }
    
    func popUntil(_ path: SFNavigationPath) {
        if self.manager.last != path {
            self.manager.removeLast()
            popUntil(path)
        }
    }
    
}

使用方法:pathManager.manager传入 NavigationStack,然后 注入.environmentObject(pathManager)

@StateObject var pathManager = PathManager()
    var body: some View {
        NavigationStack(path: $pathManager.manager){
            ZStack(alignment: .bottom) {
                TabView(selection: $viewModel.selectedTab) {
                    BaoBiaoView()
                        .tag(SFTabbarType.chartBarType)
                    YewuView()
                        .tag(SFTabbarType.yewuBarType)
                    HomeSpace()
                        .tag(SFTabbarType.homeBarType)
                    CustomersView()
                        .tag(SFTabbarType.custBarType)
                    NewsView()
                        .tag(SFTabbarType.newsBarType)
                }
                .accentColor(.red)
                .background(.red)
                .toast(isPresenting: $viewModel.showMsg, text: viewModel.msg)
                
                SFTabbarView().onAppear{//刷新消息数量
                    viewModel.getNewsNumber()
                }
            }
            .ignoresSafeArea(.all,edges: .bottom)
            .environmentObject(viewModel)
            .navigationBarTitleDisplayMode(.inline)
        }
        .environmentObject(pathManager)
@EnvironmentObject var pathManger:PathManager
    var body: some View {
        VStack {
            SFNavigationBar(showBackBtn:false,title: "报表"){
                
            }
            BaseListView(viewModel: viewModel) {
                ForEach(viewModel.datas, id: \.self) { item in
                    VStack(spacing: 0){
                        HStack {
                            Text("点击了\(item)")
                            Text("点击了\(item)")
                        }
                        .foregroundColor(.black)
                        .padding(.all,15)
                        .frame(minWidth: screenWidth,maxWidth: .infinity)
                        .background(.white)
                        Divider()
                    }
                    .onTapGesture {
                        pathManger.push(.testPath2)
                    }
                }
            }
            .pathNormalPageView()
        }
        .background(viewModel.bgColor)
    }

如果带参数可以这样用:

pathManger.push(.testPath(100))

如果是复杂参数可以这样用:

.pathCustPageView { path in
                if path == .testPath2{
                    //TODO
                }
            }

相关文章

  • SwiftUI-NavigationStack

    使用导航堆栈在根视图上显示视图堆栈。人们可以通过单击或点击NavigationLink将视图添加到堆栈顶部,并使用...

  • SwiftUI 界面大全之使用NavigationStack 实

    今天我们将探讨如何使用 SwiftUI-4 的新 Navigation Api aka NavigationSta...

  • NavigationView 基础用法

    一、介绍 在Swift中,我们使用了UINavigationController来控制界面的路由在SwiftUI中...

  • SwiftUI-NavigationPath

    您可以通过使用数据集合的绑定初始化堆栈来管理NavigationStack的状态。堆栈在集合中为堆栈上的每个视图存...

  • SwiftUI 框架之不使用NavigationLink实现路由

    实战需求 SwiftUI 框架之不使用NavigationLink实现路由式Router导航(教程含源码) 在Re...

  • Day13 - Flutter - 路由导航

    概述 路由管理 路由基本使用 命名路由使用(重点) 页面跳转的拓展 一、路由管理 1.1、认识Flutter路由路...

  • @State 介绍

    可以读取和写入由SwiftUI管理的值的属性包装类型。 SwiftUI管理声明为状态的属性的存储。当值更改时,Sw...

  • SwiftUI 属性包装器

    1.@State SwiftUI管理声明为@State的属性,当值变化时,SwiftUI会更新依赖于该值的视图结构...

  • SwiftUI-NavigationLink

    人们单击或点击导航链接以在NavigationStack或NavigationSplitView中显示视图。通过在...

  • Flutter路由,跳转传值

    路由 Flutter 中的路由就是页面跳转。通过 Navigator 组件管理路由导航。并提供了管理堆栈的方法。 ...

网友评论

      本文标题:SwiftUI 路由管理 NavigationStack

      本文链接:https://www.haomeiwen.com/subject/yzttrdtx.html