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

Xcode 13中View内使用confirmationDialog时Alert无法弹出是Bug吗

问题结论

这不是Xcode 13的Bug,是iOS 15 版本 SwiftUI 的原生设计限制:同一视图上下文下同一时间仅允许展示一个系统弹窗类组件(包含alert、confirmationDialog、sheet等),在弹窗未完全退场时触发新的弹窗请求,会被系统直接拦截。

你看到的控制台报错为系统预设的拦截提示:

Attempting to present an alert while a confirmation dialog is already presented. This is not supported.

问题原因

你的代码将alert和confirmationDialog两个弹窗修饰符都挂载到了同一个Button视图上,当你点击confirmationDialog内的按钮时,confirmationDialog本身还处于展示状态、尚未完成退场动画,此时触发alert展示的请求就会被系统拒绝。

适配iOS 15的可行解决方案
  • 方案1:调整弹窗触发时机,等confirmationDialog完全关闭后再弹出alert,代码示例如下:
struct ConfirmationDialog: View {
    @State private var showingOptions = false
    @State private var showingAlert = false

    var body: some View {
        VStack {
            Button("Show Options") {
                showingOptions = true
            }
            .alert("Alert Title", isPresented: $showingAlert, actions: {
                Button {
                    // Do nothing
                } label: {
                    Text("Okay")
                }
            }, message: {
                Text("Alert Message")
            })
            .confirmationDialog("Select option", isPresented: $showingOptions, titleVisibility: .visible) {
                Button("Show Alert") {
                    // 先关闭确认弹窗
                    showingOptions = false
                    // 等待退场动画完成后再弹出alert
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                        showingAlert = true
                    }
                }
            }
        }
    }
}
  • 方案2:拆分修饰符挂载层级,将alert修饰符挂载到父级VStack上,避免两个弹窗修饰符绑定到同一个视图节点,降低上下文冲突概率。
  • 方案3:如果你的App最低兼容版本可升级到iOS 16,使用Xcode 14+开发即可,该版本SwiftUI已优化弹窗调度逻辑,会自动等待前一个弹窗退场后再展示新的弹窗,无需额外适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:27:04