如何让SwiftUI的NavigationStack在#Preview中正常工作?
你的问题出在预览代码里没有添加navigationDestination修饰符——模拟器/真机运行的NavigationWrapper里包含了这个关键配置,但预览代码里的NavigationStack只是绑定了路由路径,却没告诉系统如何解析Route对应的视图,所以点击按钮无法触发导航。
下面是一个通用的预览包装器,专门解决这个问题,既能复用你的导航逻辑,又能在预览中正常测试导航流程:
struct PreviewNavigationStack<Route: NavigationRouteRepresentable, Content: View>: View { @StateObject private var routeManager = RouteManager<Route>() private let rootView: Content init(@ViewBuilder rootView: () -> Content) { self.rootView = rootView() } // 支持初始化时传入初始路由,方便测试深层页面 init(initialRoutes: [Route], @ViewBuilder rootView: () -> Content) { self.rootView = rootView() _routeManager = StateObject(wrappedValue: RouteManager<Route>(routes: NavigationPath(initialRoutes))) } var body: some View { NavigationStack(path: $routeManager.routes) { rootView .environmentObject(routeManager) } .navigationDestination(for: Route.self) { destination in destination.body .environmentObject(routeManager) } } } // 给RouteManager添加带初始路由的初始化方法 extension RouteManager { init(routes: NavigationPath) { self.routes = routes } }
接下来修改你的预览代码,直接使用这个包装器:
#Preview { PreviewNavigationStack(rootView: { ContentView() }) }
如果需要直接预览某个特定路由的页面(比如测试从Settings页面继续导航的流程),可以用带初始路由的初始化方法:
#Preview("Settings Page") { PreviewNavigationStack(initialRoutes: [.settings]) { ContentView() } }
这样修改后,预览中点击"Go"按钮就能正常跳转到Settings页面,和模拟器/真机表现完全一致,你不用再依赖模拟器就能在预览里测试完整的导航流程。
内容的提问来源于stack exchange,提问作者markb
相关产品推荐
相关产品推荐

