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

popover页面中关闭UIAlertController无反应或误关整个弹窗如何解决

问题根因

  • 你当前的实现每次调用presentLoadingView都会创建全新的UIAlertController实例:当你传入shouldPresent = false试图关闭加载框时,你dismiss的是刚刚新建、还未弹出的alert实例,之前已经展示在界面上的alert没有被持有引用,自然无法响应dismiss操作
  • 直接调用无前缀的dismiss(animated: true)会触发当前ViewController(也就是你的popover本身)的dismiss方法,所以会把整个popover关掉

解决方案

首先在你的popover对应的ViewController中,新增一个私有属性持有加载弹窗的引用:

// 持有加载弹窗的全局引用
private var loadingAlert: UIAlertController?

然后修改presentLoadingView的实现逻辑,分开处理弹出和关闭的场景:

private func presentLoadingView(shouldPresent: Bool) {
    // 强制主队列执行UI操作,避免CoreData异步操作导致UI调用不在主队列的问题
    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }
        if shouldPresent {
            // 避免重复弹出加载框
            guard self.loadingAlert == nil else { return }
            let alert = UIAlertController(title: nil, message: "Retrieving Owner Data", preferredStyle: .alert)
            let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
            loadingIndicator.hidesWhenStopped = true
            loadingIndicator.style = .medium
            loadingIndicator.startAnimating()
            alert.view.addSubview(loadingIndicator)
            // 存储弹窗引用
            self.loadingAlert = alert
            // 如果有自定义的presentAnimated方法可替换下方系统方法
            self.present(alert, animated: true)
        } else {
            // 用之前持有的引用关闭弹窗
            self.loadingAlert?.dismiss(animated: true)
            // 引用置空,避免下次调用出现判断异常
            self.loadingAlert = nil
        }
    }
}

使用方式

  • CoreData操作开始前调用presentLoadingView(shouldPresent: true)弹出加载框
  • CoreData异步操作完成的回调中调用presentLoadingView(shouldPresent: false)关闭加载框即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:54:03