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

SwiftUI自定义Alert点击无法关闭问题排查

问题定位与解决方法

你的问题核心出在绑定的创建方式上:

在MyView中,你用.constant(viewModel.showAlert)传递给customAlert,但.constant()创建的是单向只读绑定——它只能读取viewModel.showAlert的初始值,无法将修改反向同步回ViewModel的showAlert变量。当你点击按钮设置isPresented.wrappedValue = false时,只是修改了这个临时绑定的本地值,ViewModel里的@Published var showAlert根本没变化,所以Alert自然不会消失。

修正方法

把customAlert的绑定参数从.constant(viewModel.showAlert)改成$viewModel.showAlert即可,$符号可以直接获取@ObservedObject中@Published属性的双向绑定:

struct MyView: View {
    @ObservedObject var viewModel: CustomViewModel = CustomViewModel()
    
    var body: some View {
        VStack {
            switch viewModel.state {
            case .idle:
                Color.clear.onAppear(perform: { viewModel.doSomething() })
            case .showNewView:
                // Navigate
            }
        }
        .onAppear {
            viewModel.state = .idle
        }
        // 这里改成$viewModel.showAlert
        .customAlert(isPresented: $viewModel.showAlert)
    }
}

额外优化建议

你的自定义修饰器里的GeometryReader其实没必要(你没用到它的布局信息),可以简化alertContent的实现,同时让Alert更贴近原生样式:

@ViewBuilder
private func alertContent() -> some View {
    if isPresented.wrappedValue {
        Button(action: { isPresented.wrappedValue = false }) { 
            Text("Click Me")
                .padding()
                .background(Color.white)
                .cornerRadius(8)
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.black.opacity(0.5))
        .onTapGesture {
            isPresented.wrappedValue = false
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:25:38