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

Swift中UIAlertView无法显示的问题排查求助

搞定UIAlertView无法显示的问题

嘿,我来帮你解决这个弹窗不显示的麻烦!首先得说,UIAlertView早在iOS 8就被官方废弃了,现在都用UIAlertController啦,而且还有个很关键的点——所有UI操作必须在主线程执行,这大概率是你弹窗不出来的核心原因。

先把弹窗代码换成正确的写法

直接给你改好的示例,把原来的UIAlertView换成UIAlertController,同时解决了潜在的崩溃风险:

func handleRecievedQR(QRCode: String) {
    let scannedCode = QRCode.split(separator: ",")
    
    // 先处理QR码格式校验,避免强制解包崩溃
    guard let issuedYear = Int(scannedCode[3]),
          let issuedMonth = Int(scannedCode[4]),
          let issuedDay = Int(scannedCode[5]),
          let issuedHour = Int(scannedCode[6]),
          let issuedMin = Int(scannedCode[7]),
          scannedCode.count >= 8 else {
        // 格式错误时弹窗提示
        showAlert(title: "出错啦", message: "扫描的QR码格式不正确哦")
        return
    }
    
    let attendance = ScannedQRCode(issuer: String(scannedCode[0]),
                                   eventName: String(scannedCode[1]),
                                   eventCode: String(scannedCode[2]),
                                   issuedYear: issuedYear,
                                   issuedMonth: issuedMonth,
                                   issuedDay: issuedDay,
                                   issuedHour: issuedHour,
                                   issuedMin: issuedMin)
    
    // 扫码成功的通知弹窗
    showAlert(title: "扫码完成", message: "已成功识别签到信息")
}

// 封装弹窗工具函数,方便复用且保证主线程执行
private func showAlert(title: String, message: String) {
    DispatchQueue.main.async {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "确定", style: .default, handler: nil))
        
        // 获取当前最顶层的ViewController来present弹窗,避免present失败
        if let topVC = self.getCurrentTopViewController() {
            topVC.present(alert, animated: true, completion: nil)
        }
    }
}

// 辅助函数:找到当前正在显示的最顶层ViewController
private func getCurrentTopViewController() -> UIViewController? {
    var topVC = UIApplication.shared.windows.first?.rootViewController
    while let presentedVC = topVC?.presentedViewController {
        topVC = presentedVC
    }
    return topVC
}

几个必须注意的关键点

  • 一定要在主线程执行UI操作:扫码回调通常是在子线程触发的,如果直接在子线程调用弹窗,系统会忽略这个UI请求,所以必须用DispatchQueue.main.async把弹窗代码包裹起来。
  • 找对弹窗的载体ViewController:不能随便拿个ViewController就present,得找当前屏幕上最顶层的那个VC,否则可能因为当前有其他弹窗、导航栈层级问题导致present失败。
  • 别用强制解包:你原来代码里的Int(scannedCode[3])!写法非常危险,万一QR码格式不符合预期,直接就会崩溃,用guard let做可选绑定才是安全的做法。

如果坚持要用UIAlertView(真的不推荐,iOS 13之后可能完全失效),那也得把它放到主线程里调用,还要设置delegate,但还是建议直接升级到UIAlertController,毕竟是官方现在主推的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:29:02