iOS 弹窗失败问题处理

报错原因:

问题在于试图在一个 UIAlertController(已经显示的弹窗)上再展示另一个 UIAlertController。这在 iOS 中是不允许的,因为 UIAlertController 不能作为其他视图控制器的 presenter。
为了确保你的 AlertQueueManager 正确工作,并避免出现试图在非窗口层级中的视图控制器上展示新视图控制器的问题,我们需要确保每次只在最顶层的有效视图控制器上展示新的 UIAlertController。

class AlertQueueManager: NSObject {
    static let shared = AlertQueueManager()
       
       private var alertQueue: [(UIViewController) -> Void] = []
       private var isShowing = false
       
    private override init() {}
       
   
       
       func enqueue(alertBuilder: @escaping (UIViewController) -> Void) {
            DispatchQueue.main.async {
                self.alertQueue.append(alertBuilder)
                self.processNext()
            }
        }
        
        private func processNext() {
            guard !isShowing, let keyWindow = getKeyWindow(), let rootVC = keyWindow.rootViewController, !alertQueue.isEmpty else { return }
            
            isShowing = true
            let alertBuilder = alertQueue.removeFirst()
            alertBuilder(rootVC)
        }
        
        func dequeue() {
            isShowing = false
            processNext()
        }
    
       
       private var topViewController: UIViewController? {
           guard var top = getKeyWindow()?.rootViewController else { return nil }
           while let presented = top.presentedViewController {
               top = presented
           }
           return top
       }

}

具体用法

et alert = UIAlertController(title: downloadTileInfo, message: "0%", preferredStyle: .alert)
let heightConstraint = NSLayoutConstraint(item: alert.view!, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 200)
alert.view.addConstraint(heightConstraint)

    // 添加进度条
    let progressBar = UIProgressView(progressViewStyle: .default)
    progressBar.translatesAutoresizingMaskIntoConstraints = false
    alert.view.addSubview(progressBar)
    progressBar.centerXAnchor.constraint(equalTo: alert.view.centerXAnchor).isActive = true
    progressBar.centerYAnchor.constraint(equalTo: alert.view.centerYAnchor).isActive = true
    progressBar.widthAnchor.constraint(equalToConstant: 200).isActive = true
    
    let cancelAction = UIAlertAction(title: "取消", style: .cancel){[weak self]  _ in
        self?.cancelDownload()
    }
    
    alert.addAction(cancelAction)
    
    // 入队
    AlertQueueManager.shared.enqueue { viewController in
        viewController.present(alert, animated: true) {
        }
    }
取消

DispatchQueue.main.async {
alert.dismiss(animated: true)
AlertQueueManager.shared.dequeue()
}
这是在处理多个弹窗的一点心得,与诸位共勉!!!希望能帮助需要的你

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容