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

SwiftUI中点击OK按钮后Alert需点击其他控件才显示的原因

问题原因

你的问题核心在于嵌套的ModalOkMsgBoxInfo不是可观察对象,内部属性变化无法触发UI更新:
DataViewModel中的@Published var gOKMsgBox仅会在gOKMsgBox这个对象本身被替换时发布更新通知,而修改它内部的bShow、strMsg属性,并不会触发DataViewModel的状态变更通知。SwiftUI的UI只有收到明确的状态更新信号才会刷新,所以Alert不会立即弹出,直到其他UI操作触发视图刷新时才会显示。


修复方案

方案1:让嵌套类成为可观察对象

将ModalOkMsgBoxInfo改为遵循ObservableObject协议,并把需要触发UI更新的属性标记为@Published:

class ModalOkMsgBoxInfo: ObservableObject {
    @Published var bShow: Bool = false
    @Published var strMsg: String = ""
    
    func showOkMsgBox(msg: String) {
        strMsg = msg
        bShow = true
    }
}

同时修正全局函数里的错误用法(全局函数不需要@ObservedObject):

func showOkMsgBox(msg: String) {
    let gDVM = DataViewModel.shared
    gDVM.gOKMsgBox.strMsg = msg
    gDVM.gOKMsgBox.bShow = true
}

方案2:简化数据模型(更推荐)

如果不需要嵌套类,直接在DataViewModel中使用独立的@Published属性会更简洁:

class DataViewModel: ObservableObject {
    static let shared = DataViewModel()
    
    @Published var showAlert = false
    @Published var alertMessage = ""
    
    func showOkMsgBox(msg: String) {
        alertMessage = msg
        showAlert = true
    }
}

对应修改ContentView的Alert绑定:

struct ContentView: View {
    @ObservedObject var gDVM = DataViewModel.shared
    
    var body: some View {
        NavigationView {
            MenuView(menuOptions: menuOptions, curSelMenu: $currentMenu)
            ConfigView()
        }
        .alert(isPresented: $gDVM.showAlert) {
            Alert(title: Text("Title"), message: Text(gDVM.alertMessage))
        }
    }
}

触发代码简化为:

func showOkMsgBox(msg: String) {
    DataViewModel.shared.showOkMsgBox(msg: msg)
}

额外注意事项
  • SwiftUI中@ObservedObject仅用于视图内部引用外部可观察对象,全局函数/普通方法中直接访问共享实例即可,不需要添加该属性包装器。
  • 所有需要触发UI更新的状态属性,必须通过@Published标记,或者手动发送objectWillChange通知(@Published是更简洁的实现方式)。

内容的提问来源于stack exchange,提问作者c00000fd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 23:50:25