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

SwiftUI中ProgressView的激活与停用时机咨询

解决ProgressView显示异常的问题

你的代码里激活ProgressView的时机不对,导致它无法在耗时任务全程持续显示,调整方案如下:

  • 激活ProgressView:直接在按钮的点击闭包开头设置showProgress = true,不需要放到全局队列的DispatchQueue.main.async里。因为按钮点击回调本身就在主队列执行,这里设置能立刻触发界面更新,让ProgressView马上显示。
  • 停用ProgressView:保持原位置不变,在耗时任务完成后,通过DispatchQueue.main.async将showProgress设为false,确保在主队列更新UI。

修改后的完整代码:

struct ContentViewDispatch: View{
    @State var button_tap_count = 0
    @State var dispatch_start = 0
    @State var i = 0
    @State var showProgress = false
    var body: some View{
        VStack{
            Text("Tapped: \(button_tap_count)")
            Text("Dispatch: \(dispatch_start)")
            Text("number: \(i)")
            Button("reset"){
                i = 0
            }
            ProgressView().progressViewStyle(CircularProgressViewStyle()).opacity(showProgress ? 1 : 0)
            
            Button("count"){
                button_tap_count += 1
                showProgress = true  // <----- 调整到此处激活
                var k = i
                DispatchQueue.global(qos: .userInitiated).async {
                    DispatchQueue.main.async {
                        dispatch_start += 1
                    }
                    for _ in 0..<5_000_000{
                        k += 1
                    }
                    DispatchQueue.main.async {
                        showProgress = false  // <------ 停用位置保持不变
                        i = k
                    }
                }
            }
        }
    }
}

调整原因

原代码中,激活ProgressView的操作被嵌套在全局队列的主异步里,这会导致UI更新被延迟到下一个主运行循环。而耗时任务在全局队列里是同步执行的,可能在UI更新完成前就已经执行了一部分甚至全部,导致ProgressView要么闪一下就消失,要么根本不显示。把激活操作移到按钮点击的主队列直接执行,能让ProgressView立刻显示,直到耗时任务完成后再隐藏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:01:14