更新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(),但它似乎也没有工作。

+0

你知道你的函数在哪个线程上运行吗?你可以在你的函数中设置一个断点,并且当断点被击中时,检查它在Xcode左边运行的线程。如果它不是主线程(线程1),那么这可能是你的问题,因为所有的UI更新都要在主线程上运行。要解决这个问题,请查看'DispatchQueue.main.async'。 – pbodsk

假设您正在主线程上运行,那么您将阻塞,直到方法结束。无论哪种“需要”样式方法(setNeedsDisplay,displayAsNeeded等),您尝试使用实际的重新显示都不会发生,直到方法结束(显示更新被分组以避免它不断更新)。

你可以做的是把工作推上一个后台线程,然后把UI更新返回到类似这样的主线程:

DispatchQueue.global(qos: .background).async { 
    for item in collection { 
     DispatchQueue.main.async { 
      progressBar.increment(by:1) 
      progressBar.display() 
     } 
    } 
} 

当然,这会引发其他问题,如用户可以现在在后台线程正在处理的过程中与UI进行交互,您需要对这些线程进行处理。

如果您已经在后台线程中运行,那么您只需将进度条更新发送到主线程。

+0

我没有具体说明在任何特定线程上运行的方法,所以我假设它在主线程上运行。 (还没有阅读过关于多线程的工作,以前从来没有故意做过任何事情。)你所说的话证实了我在屏幕更新时所怀疑的内容。我会阅读DispatchQueue并确认它修复了我的问题。谢谢! –

+0

这解决了更新条的问题。正如你所提到的那样,我还需要清理其他一些问题,但这是另一篇文章的问题。谢谢! –