You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让SwiftUI的NavigationStack在#Preview中正常工作?

SwiftUI预览专用NavigationStack包装器实现

你的问题出在预览代码里没有添加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:10:00