SwiftUI通过ContextMenu弹出模态视图重复初始化问题求助
解决模态视图重复初始化的问题
你遇到的问题根源在于把.sheet修饰符附加到了上下文菜单里的Button上。系统在处理contextMenu时,会多次渲染菜单内的视图(比如菜单弹出前后的状态变化),这就导致绑定在Button上的DetailView被重复初始化了两次。
修正方案:将.sheet移到稳定的父视图上
把sheet的绑定从Button转移到ContentView的根视图上,这样sheet的展示逻辑只和isModal状态绑定,不会因为菜单的重复渲染而触发多次初始化。
修正后的ContentView代码:
struct ContentView: View { @State var isModal: Bool = false var body: some View { Group { Text("Main view") } .contextMenu { Button("Present Detail") { self.isModal = true } } // 将sheet移到根视图层级,避免重复初始化 .sheet(isPresented: $isModal) { DetailView() } } }
DetailView保持不变:
struct DetailView: View { var body: some View { Text("Detail View") } }
额外建议:网络请求的最佳实践
如果要在DetailView中发起网络请求,建议用@StateObject管理请求逻辑(比如一个ViewModel),并在onAppear中触发请求。这样即使视图有意外的重建,ViewModel也只会初始化一次,避免重复发起请求:
// 定义ViewModel管理网络请求 class DetailViewModel: ObservableObject { func fetchData() { // 这里放置你的网络请求逻辑 print("发起单次网络请求") } } struct DetailView: View { // @StateObject确保ViewModel仅初始化一次 @StateObject private var viewModel = DetailViewModel() var body: some View { Text("Detail View") .onAppear { // 视图出现时触发请求 viewModel.fetchData() } } }
这样调整后,不仅解决了模态视图重复初始化的问题,也能保证网络请求只会被执行一次。
内容的提问来源于stack exchange,提问作者patrickS
相关产品推荐
相关产品推荐

