如何将UIAlert的用户选择结果返回给对应Delegate代理方法
核心结论
同步返回Bool的代理方法没办法直接获取异步UIAlert的用户选择结果,因为UIAlert弹出后不会阻塞线程,方法会在用户点击前就执行返回逻辑。下面提供两种适配方案,优先匹配你不想修改原有Delegate协议、继续使用UIAlert的需求。
方案1:完全不修改原有Delegate协议(优先推荐)
适用场景:你可以主动触发RouteManager的更新流程,不会产生业务冲突。
实现思路:第一次触发代理时直接返回false中断本次更新,弹出Alert等待用户选择,用户点击确认后标记状态,主动重新触发更新流程,第二次触发代理时直接返回true执行更新。
extension MyController : RouteManagerDelegate { // 私有标记位:记录用户是否已经确认要更新 private var isConfirmedToUpdate: Bool = false func routeShouldUpdateUnfinished() -> Bool { // 已经过用户确认,直接返回true,同时重置标记避免后续逻辑异常 guard !isConfirmedToUpdate else { isConfirmedToUpdate = false return true } // 首次调用弹出确认弹窗 let confirmationAlert = UIAlertController(title: "当前路线未完成", message: "是否继续更新?", preferredStyle: .alert) confirmationAlert.addAction(UIAlertAction(title: "是", style: .destructive) { [weak self] _ in guard let self = self else { return } // 标记用户已确认 self.isConfirmedToUpdate = true // 主动重新触发RouteManager的更新流程,此时再走代理判断会直接返回true RouteManager.shared.triggerUpdate() }) confirmationAlert.addAction(UIAlertAction(title: "否", style: .cancel)) self.present(confirmationAlert, animated: true) // 首次调用直接返回false,中断本次未授权的更新流程 return false } }
方案2:最小化修改Delegate协议(规范通用方案)
如果无法主动触发RouteManager的更新流程,建议把同步代理改成异步回调形式,这是iOS异步交互的标准实现方式,后续扩展也更灵活。
- 修改Delegate协议定义:
protocol RouteManagerDelegate { func routeShouldUpdateUnfinished(completion: @escaping (Bool) -> Void) }
- 修改原Delegate调用方的逻辑:
// 原同步调用逻辑 // let shouldUpdate = delegate?.routeShouldUpdateUnfinished() ?? false // if shouldUpdate { // 执行更新逻辑 // } // 替换为异步调用逻辑 delegate?.routeShouldUpdateUnfinished(completion: { [weak self] shouldUpdate in guard let self = self else { return } if shouldUpdate { // 执行原来的更新逻辑 } })
- 你的代理实现修改为:
extension MyController : RouteManagerDelegate { func routeShouldUpdateUnfinished(completion: @escaping (Bool) -> Void) { let confirmationAlert = UIAlertController(title: "当前路线未完成", message: "是否继续更新?", preferredStyle: .alert) confirmationAlert.addAction(UIAlertAction(title: "是", style: .destructive) { _ in completion(true) }) confirmationAlert.addAction(UIAlertAction(title: "否", style: .cancel) { _ in completion(false) }) self.present(confirmationAlert, animated: true) } }
内容的提问来源于stack exchange,提问作者Tyson Freeze
相关产品推荐
相关产品推荐

