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

嵌套UIAlert问题:UIAlertAction中弹窗后逻辑重复触发

问题解决:UIAlertAction等待第二个弹窗操作完成

问题场景

在第一个UIAlertAction的处理逻辑中,调用deletePoints方法展示第二个UIAlertController时遇到两个问题:

  • 第一个弹窗的Action不会等待第二个弹窗的操作完成,直接执行后续代码
  • 第二个弹窗结束后,第一个Action的逻辑似乎被触发了两次

问题根源

原代码中deletePoints是同步调用,执行完弹窗展示后立刻回到第一个Action的handler继续执行后续的积分添加逻辑,完全没有等待用户对第二个弹窗的操作。同时,循环遍历selectedIndexPaths的逻辑可能因弹窗展示时机问题导致重复执行。

解决方案

通过**闭包(Completion Handler)**让deletePoints在用户完成第二个弹窗操作后,再回调第一个Action的handler执行后续逻辑:

步骤1:修改deletePoints方法,添加Completion闭包

func deletePoints(table: [Tables], completion: @escaping (Bool) -> Void) {
    let pointsAlertController = UIAlertController(title: "Some text", message:
        "Delete points?", preferredStyle: .alert)
    
    // 取消按钮:不删除积分,回调false
    pointsAlertController.addAction(UIAlertAction(title: "Nein", style: .cancel, handler: { _ in
        completion(false)
    }))
    
    // 确认按钮:删除积分,回调true
    pointsAlertController.addAction(UIAlertAction(title: "Ja", style: .default, handler: { [self] _ in
        table[0].points -= 100
        self.tablesService?.update(updatedTable: table[0])
        completion(true)
    }))

    self.present(pointsAlertController, animated: true)
}

步骤2:修改第一个Action的handler逻辑,等待闭包回调

将原本直接执行的后续积分逻辑放到deletePoints的completion闭包中,确保只有用户操作完第二个弹窗后才执行:

alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { [self] _ in
    for (index, indexPath) in selectedIndexPaths.enumerated() {
        // some code...
        
        if table[0].points >= 100 {
            // 调用deletePoints,等待用户操作完成后再执行后续逻辑
            deletePoints(table: table) { [self] _ in
                // 这里放原本在deletePoints之后的代码
                if position?.category == 0 {
                    if table[0].segment == 3 {
                        table[0].points += 5
                        self.tablesService?.update(updatedTable: table[0])
                    }
                }
                // some code...
            }
        } else {
            // 如果不需要弹窗,直接执行后续逻辑
            if position?.category == 0 {
                if table[0].segment == 3 {
                    table[0].points += 5
                    self.tablesService?.update(updatedTable: table[0])
                }
            }
            // some code...
        }
    }
}))

额外注意点

  • 确保selectedIndexPaths的遍历逻辑不会因弹窗重复触发,建议在第一个弹窗的Action执行时先禁用相关交互或标记状态,避免重复触发
  • 闭包中注意捕获self的循环引用问题,这里用[self]是安全的,因为UIAlertAction的handler会在执行后释放

内容的提问来源于stack exchange,提问作者Gökhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:44:57