因為對moya框架的使用,給了我啟發(fā),花點時間封裝了下 NavigationStack 的路由管理。不多說,上代碼:
先定義個Path的枚舉,對應APP的每個頁面,可帶參數(shù)(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)//帶參數(shù)類型測試
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 協(xié)議代理,協(xié)議方法 有push...等這些一看就懂。
protocol SFNavigationDelegate{
associatedtype Route = SFNavigationPath
func push(_ path:Route)
func pop()
func popToRoot()
func popUntil(_ path:Route)
}
繼續(xù)做一個View分類用來 導航頁面用,具體就是用到的時候,需要實現(xiàn)調用,當然也可以自己實現(xiàn)navigationDestination,具體看業(yè)務需求吧。
extension View{
//返回默認,或者簡單參數(shù)的頁面
func pathNormalPageView() -> some View {
self.navigationDestination(for: SFNavigationPath.self) { path in
path.pageParamView()
}
}
//如果復雜參數(shù),可以用這個
func pathCustPageView(@ViewBuilder destination: @escaping (_ path:SFNavigationPath) -> some View) -> some View{
self.navigationDestination(for: SFNavigationPath.self, destination: destination)
}
}
最后寫一個manger 遵守協(xié)議來管理導航
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{//刷新消息數(shù)量
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)
}
如果帶參數(shù)可以這樣用:
pathManger.push(.testPath(100))
如果是復雜參數(shù)可以這樣用:
.pathCustPageView { path in
if path == .testPath2{
//TODO
}
}