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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:12:37