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

如何通过确认弹窗控制SwiftUI Sheet的滑动关闭行为

解决SwiftUI Sheet下滑关闭时的确认弹窗问题

要实现Sheet下滑关闭时弹出确认弹窗(而非直接阻止),核心思路是自定义绑定拦截Sheet的关闭请求,结合未保存状态判断是否触发确认弹窗。以下是完整实现方案:

步骤1:添加状态变量

新增跟踪表单输入和未保存状态的变量:

  • name:绑定到TextField的输入值,替换原来的.constant
  • hasUnsavedChanges:判断是否存在未保存的修改

步骤2:创建自定义绑定

通过自定义Binding<Bool>拦截Sheet的关闭请求:当用户尝试关闭(包括下滑和Cancel按钮点击)时,先检查是否有未保存更改,有则弹出确认弹窗,无则直接关闭。

完整代码实现

struct ContentView: View {
    @State var showSheet = false
    @State var showConfirmation = false
    @State var name = "Hello, World." // 替换constant,绑定输入框
    @State var hasUnsavedChanges = false

    // 自定义绑定,拦截Sheet关闭请求
    private var sheetBinding: Binding<Bool> {
        Binding(
            get: { showSheet },
            set: { newValue in
                guard !newValue else {
                    showSheet = true
                    return
                }
                // 用户尝试关闭Sheet,检查未保存状态
                if hasUnsavedChanges {
                    showConfirmation = true
                } else {
                    showSheet = false
                }
            }
        )
    }

    var body: some View {
        Form {
            Button("Show Sheet") {
                showSheet = true
            }
        }
        .sheet(isPresented: sheetBinding) { // 使用自定义绑定
            NavigationStack {
                Form {
                    TextField("Name", text: $name)
                        .onChange(of: name) { newValue in
                            // 对比初始值,更新未保存状态
                            hasUnsavedChanges = newValue != "Hello, World."
                        }
                }
                .toolbar {
                    ToolbarItem(placement: .cancellationAction) {
                        Button("Cancel") {
                            // 点击Cancel时触发自定义绑定的关闭逻辑
                            showSheet = false
                        }
                    }
                }
                .confirmationDialog("是否放弃更改?", isPresented: $showConfirmation) {
                    Button("放弃更改", role: .destructive) {
                        showSheet = false
                    }
                    Button("取消", role: .cancel) {}
                }
                // 移除interactiveDismissDisabled(),让下滑关闭触发绑定逻辑
            }
        }
    }
}

关键说明

  1. 自定义绑定的作用:无论用户通过下滑还是Cancel按钮关闭Sheet,都会触发绑定的set方法,统一处理关闭逻辑,避免重复代码。
  2. 未保存状态判断:通过onChange监听输入框值的变化,对比初始值来更新hasUnsavedChanges,确保仅在有修改时才弹出确认。
  3. 确认弹窗完善:添加了「取消」按钮,让用户可以放弃关闭操作,回到表单页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:52:37