更新ViewController中的NSProgress显示功能循环
我又回到了Hive Mind!更新ViewController中的NSProgress显示功能循环
在我的ViewController类中,我有一个函数遍历数组中的一系列项。我想要发生的是在循环的每次迭代中更新我的进度条,但它似乎并没有更新屏幕上的进度条,直到它完成整个循环并退出我的函数。
我敢肯定,这只是因为视图只得到一次通过应用循环每次重绘(我可能不是这里使用正确的术语。)
什么是正确的方法来强制ViewController视图更新,而我仍然在我的ViewController函数循环内?
这里基本上是我在做什么现在:
func myFunction() {
for item in collection {
progressBar.increment(by:1)
progressBar.display()
}
// execute my other code
}
如果没有工作,我尝试了progressBar.draw方法之后加入needsSetDisplay,像这样:
func myFunction() {
for item in collection {
progressBar.increment(by:1)
progressBar.display()
let rect = self.view.visibleRect
self.view.needsSetDisplay(rect)
}
// execute my other code
}
但它仍然没有工作。
我确定有一种方法可以完成我需要做的事情,但我怀疑它涉及到更高级的事情,比如运行多个进程,但我可能没有资格做到这一点,因为我是Swift的新手,至今已经用Obj-C编码至少10年了(也就是我忘记了大部分知识)
谢谢!
编辑我尝试失败的另一件事是打电话给progressBar.displayAsNeeded()
,但它似乎也没有工作。
假设您正在主线程上运行,那么您将阻塞,直到方法结束。无论哪种“需要”样式方法(setNeedsDisplay,displayAsNeeded等),您尝试使用实际的重新显示都不会发生,直到方法结束(显示更新被分组以避免它不断更新)。
你可以做的是把工作推上一个后台线程,然后把UI更新返回到类似这样的主线程:
DispatchQueue.global(qos: .background).async {
for item in collection {
DispatchQueue.main.async {
progressBar.increment(by:1)
progressBar.display()
}
}
}
当然,这会引发其他问题,如用户可以现在在后台线程正在处理的过程中与UI进行交互,您需要对这些线程进行处理。
如果您已经在后台线程中运行,那么您只需将进度条更新发送到主线程。
我没有具体说明在任何特定线程上运行的方法,所以我假设它在主线程上运行。 (还没有阅读过关于多线程的工作,以前从来没有故意做过任何事情。)你所说的话证实了我在屏幕更新时所怀疑的内容。我会阅读DispatchQueue并确认它修复了我的问题。谢谢! –
这解决了更新条的问题。正如你所提到的那样,我还需要清理其他一些问题,但这是另一篇文章的问题。谢谢! –
你知道你的函数在哪个线程上运行吗?你可以在你的函数中设置一个断点,并且当断点被击中时,检查它在Xcode左边运行的线程。如果它不是主线程(线程1),那么这可能是你的问题,因为所有的UI更新都要在主线程上运行。要解决这个问题,请查看'DispatchQueue.main.async'。 – pbodsk