diff --git a/suixinkan/App/Navigation/AppTab.swift b/suixinkan/App/Navigation/AppTab.swift index ba5a6df..1a64298 100644 --- a/suixinkan/App/Navigation/AppTab.swift +++ b/suixinkan/App/Navigation/AppTab.swift @@ -29,19 +29,6 @@ enum AppTab: String, CaseIterable, Identifiable, Hashable { } } - var systemImage: String { - switch self { - case .home: - "house" - case .orders: - "doc.text" - case .statistics: - "chart.bar" - case .profile: - "person" - } - } - /// 当前 Tab 处于选中状态时使用的本地图片资源名。 var selectedImageName: String { switch self { @@ -83,9 +70,4 @@ enum AppTab: String, CaseIterable, Identifiable, Hashable { ProfileRootView() } } - - @ViewBuilder - var label: some View { - Label(title, systemImage: systemImage) - } } diff --git a/suixinkan/App/Navigation/NavigationRouter.swift b/suixinkan/App/Navigation/NavigationRouter.swift index ca211a8..d761cdd 100644 --- a/suixinkan/App/Navigation/NavigationRouter.swift +++ b/suixinkan/App/Navigation/NavigationRouter.swift @@ -100,16 +100,6 @@ final class AppRouter: ObservableObject { return router } - /// 生成 SwiftUI NavigationStack 可使用的路径绑定。 - func binding(for tab: AppTab) -> Binding<[AppRoute]> { - let router = router(for: tab) - - return Binding( - get: { router.path }, - set: { router.path = $0 } - ) - } - /// 切换到指定主 Tab。 func select(_ tab: AppTab) { selectedTab = tab diff --git a/suixinkan/Features/Main/Main.md b/suixinkan/Features/Main/Main.md index 30d2281..f1073e1 100644 --- a/suixinkan/Features/Main/Main.md +++ b/suixinkan/Features/Main/Main.md @@ -28,8 +28,8 @@ Main 模块负责登录后的主界面 Tab 容器,以及当前尚未迁移页 2. `TabView` 使用内部 `MainTabSelection` 作为选择值,普通 Tab 映射到 `AppTab`,扫码映射到 `.scanner`。 3. 普通 Tab 切换时调用 `AppRouter.select(_:)` 更新当前业务 Tab。 4. 每个普通 Tab 通过 `TabNavigationStackHost` 创建自己的 `NavigationStack(path:)`。 -5. 路径绑定来自 `appRouter.binding(for:)`。 -6. Tab 内页面需要进入尚未迁移的子页面时,通过当前 Tab 注入的 `RouterPath` push 一个 `AppRoute.placeholder`。 +5. 导航栈宿主直接观察当前 Tab 对应的 `RouterPath`,并把 `$router.path` 绑定给 `NavigationStack`。 +6. Tab 内页面需要进入子页面时,通过当前 Tab 注入的 `RouterPath` push 对应 `AppRoute`。 7. `navigationDestination` 根据 `AppRoute` 展示详情页。 8. 子页面展示时读取 `AppRoute.hidesTabBarWhenPushed`,默认隐藏底部 TabBar。 diff --git a/suixinkan/Features/Main/Views/MainTabsView.swift b/suixinkan/Features/Main/Views/MainTabsView.swift index 1a7a4e3..f61347a 100644 --- a/suixinkan/Features/Main/Views/MainTabsView.swift +++ b/suixinkan/Features/Main/Views/MainTabsView.swift @@ -141,7 +141,17 @@ private struct TabNavigationStackHost: View { let tab: AppTab var body: some View { - NavigationStack(path: appRouter.binding(for: tab)) { + TabNavigationStackContent(tab: tab, router: appRouter.router(for: tab)) + } +} + +/// 直接观察单个 Tab 的路由路径,确保子页面修改 RouterPath 后导航栈能立即响应。 +private struct TabNavigationStackContent: View { + let tab: AppTab + @ObservedObject var router: RouterPath + + var body: some View { + NavigationStack(path: $router.path) { tab.rootView .navigationTitle(tab.title) .navigationDestination(for: AppRoute.self) { route in @@ -149,7 +159,7 @@ private struct TabNavigationStackHost: View { .toolbar(route.hidesTabBarWhenPushed ? .hidden : .visible, for: .tabBar) } } - .environmentObject(appRouter.router(for: tab)) + .environmentObject(router) } } diff --git a/suixinkanTests/NavigationRouterTests.swift b/suixinkanTests/NavigationRouterTests.swift index f201841..305ef56 100644 --- a/suixinkanTests/NavigationRouterTests.swift +++ b/suixinkanTests/NavigationRouterTests.swift @@ -64,6 +64,16 @@ final class NavigationRouterTests: XCTestCase { XCTAssertNil(router.pendingOrderScanCode) } + /// 测试个人中心系统设置路由可压入“我的”Tab 导航栈。 + func testProfileSettingsRouteCanBePushedIntoProfileTabPath() { + let appRouter = AppRouter() + let profileRouter = appRouter.router(for: .profile) + + profileRouter.navigate(to: .profile(.settings)) + + XCTAssertEqual(profileRouter.path.last, .profile(.settings)) + } + /// 测试订单模块真实路由可被压入导航栈。 func testOrderRoutesCanBePushedIntoRouterPath() throws { let router = RouterPath()