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
相关产品推荐
相关产品推荐

