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

Swift 4中如何在压缩文件时显示JGProgressHUD进度提示?

解决Zip框架进度回调中JGProgressHUD延迟显示的问题

嗨,这个问题我做文件压缩功能时也踩过一模一样的坑!核心原因其实很好理解:所有UI相关操作必须在主线程执行,而marmelroy/Zip框架的进度回调闭包是在后台线程触发的,这就导致HUD的更新被系统延迟处理,直到压缩操作完成、主线程空闲后才一次性显示出来。

问题根源拆解

Zip框架为了避免阻塞主线程(防止界面卡死),会把压缩/解压这类耗时操作放到后台队列执行,对应的进度回调闭包自然也运行在后台线程里。而JGProgressHUD是UI控件,iOS系统明确规定:所有UI的创建、更新、显示操作都必须在主线程完成,后台线程的UI操作会被系统暂存,直到主线程有空才会处理——这就是你看到HUD只在结束后才显示的直接原因。

具体解决代码

只需要把进度闭包和完成回调里的HUD操作,用DispatchQueue.main.async包裹起来,强制切换到主线程执行即可:

func quickZipFiles() {
    // 初始化并显示HUD(确保在主线程执行,这里如果是在ViewController方法里调用,默认就是主线程)
    let hud = JGProgressHUD(style: .dark)
    hud.textLabel.text = "正在压缩..."
    hud.show(in: self.view)
    
    let filePaths = ["path/to/target/file1", "path/to/target/file2"]
    let zipOutputPath = "path/to/save/zip/file.zip"
    
    Zip.zipFiles(paths: filePaths, zipFilePath: zipOutputPath, progress: { progress in
        // 把进度更新操作切回主线程
        DispatchQueue.main.async {
            hud.progress = progress
        }
    }) { success, error in
        // 完成回调里的HUD收尾操作同样要切主线程
        DispatchQueue.main.async {
            if let error = error {
                hud.textLabel.text = "压缩失败:\(error.localizedDescription)"
                hud.dismiss(afterDelay: 2)
            } else {
                hud.textLabel.text = "压缩完成"
                hud.dismiss(afterDelay: 1)
            }
        }
    }
}

额外注意事项

  • 你在viewDidLoad里调用HUD正常,是因为viewDidLoad本身就在主线程执行,所以UI操作不受限制。
  • 不仅是进度更新,HUD的show、dismiss、文字修改等所有操作,只要是在后台线程触发的回调里,都必须包裹到DispatchQueue.main.async中。
  • 别尝试把压缩操作挪到主线程执行,那样会导致界面完全卡死,Zip框架的后台处理设计是合理的,我们只需要把UI操作切回主线程就好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:10:07