SwiftUI弹窗Alert首次点击确认按钮无响应问题求助
问题原因与解决方案
你的代码首次点击Confirm无响应,核心原因是状态更新的竞态冲突:
- TextField直接绑定
self.options.name,而Confirm按钮的disabled状态完全依赖这个值是否为空。 - 首次输入名称后,
options.name的状态更新与Alert的isPresented(即isShowingNameInput)状态更新(点击Confirm需关闭Alert)几乎同步触发,SwiftUI异步的视图更新机制导致首次点击时,按钮的action被状态更新流程干扰,没能正常执行。
修复方案一:分离输入状态(推荐)
新增一个本地@State变量专门绑定TextField的输入内容,点击Confirm时再将值同步到options,彻底规避状态冲突:
// 在视图内部添加本地输入状态变量 @State private var tempTaskName = "" // 修改原按钮与Alert代码 Button(action: { self.isShowingNameInput = true // 弹出Alert时清空临时输入框 self.tempTaskName = "" }) { Text("SAVE") } .alert("Task Name", isPresented: self.$isShowingNameInput, actions: { TextField("", text: self.$tempTaskName) Button(action: { // 将临时输入值同步到options self.options.name = self.tempTaskName log("Saved \(self.options.name)") self.presentationMode.wrappedValue.dismiss() }) { Text("Confirm") }.disabled(self.tempTaskName.isEmpty) Button(role: .cancel, action: {}) { Text("Cancel") } }, message: {})
修复方案二:调整状态更新顺序
如果不想新增本地变量,可以手动指定状态更新顺序,确保Alert先完成关闭流程,再执行后续操作:
Button(action: { // 先关闭Alert,再延迟执行日志与返回操作 self.isShowingNameInput = false DispatchQueue.main.async { log("Saved \(self.options.name)") self.presentationMode.wrappedValue.dismiss() } }) { Text("Confirm") }.disabled(self.options.name.isEmpty)
内容的提问来源于stack exchange,提问作者user1385809
相关产品推荐
相关产品推荐

