如何在SwiftUI的sheet中配置NavigationLink跳转并同步搜索数据
根本原因
NavigationLink必须嵌套在NavigationView(iOS15及以下)或NavigationStack(iOS16+)导航容器内才会生效,你当前sheet内的VStack没有外层导航容器,所以NavigationLink处于不可用状态。同时你的禁止下拉关闭代码位置写错、参数逻辑也不正确。
修复代码(WelcomeView的sheet部分)
.sheet(isPresented: $showingDetail) { // 新增导航容器包裹sheet内容 NavigationView { VStack { NavigationLink(destination: ContentView(viewModel: viewModel)){ Text("Return to Search") } // 无需循环取最后一项,直接拿数组last属性更简洁 if let latestCity = viewModel.cityNameList.last { DetailView(detail: latestCity) } } } // 直接传true即可全局禁止sheet下拉关闭,不需要绑定多余变量 .interactiveDismissDisabled(true) }
问题2:搜索记录同步到ContentView解决方案
根本原因
你当前WelcomeView和ContentView都通过@StateObject独立初始化了WeatherViewModel,两个是完全隔离的实例,数据不会互通。你不需要在NavigationLink中重复调用fetchWeather,只需要共享同一个ViewModel实例即可实现数据同步。
修复步骤
- 修改ContentView的ViewModel声明,改为从外部传入,不要自己初始化:
struct ContentView: View { // 改为@ObservedObject,接收外部传入的ViewModel实例 @ObservedObject var viewModel: WeatherViewModel @State private var cityName = "" @State var showingDetail = false // 其余init、body代码保持不变 }
- 上一步修复的WelcomeView的NavigationLink已经将自身的ViewModel实例传给了ContentView,两个页面共用同一个实例,WelcomeView中存储的搜索记录会自动在ContentView的列表中渲染,不需要额外调用接口。
可选优化项
- 删除ContentView的
onAppear中的viewModel.fetchWeather(for: cityName)逻辑,刚进入页面cityName为空,调用只会产生无效请求 - WelcomeView外层不需要套
Section,Section仅用于List/Form组件内,直接用VStack即可
内容的提问来源于stack exchange,提问作者JS_is_awesome18
相关产品推荐
相关产品推荐

