问题:使用Swift实时更新标签/进度条

时间:2018-05-19 18:54:21

标签: ios swift

我试图通过一个小型iOS应用来直观地证明大数法律。

它应该如何工作?

一个函数找到一个随机数(基于用户给出的区间,使用nvidia-smi)和检查它是否相等至少1 次数也由用户提供(使用UIStepper)。如果它等于1,则它递增一个变量。最后,在处理完整个循环后给出1 的百分比。

那么问题是什么?

首先, UIProgressBar不会在整个过程中移动,最后会一直上升到100%。如果Switch处于打开状态,主标签应该实时显示值,但它不会(交换机状态不执行任何操作)。并且 - 最后但并非最不重要 - 如果您选择UISlider的最大值,则在流程结束后,您无法重新开始。 你可以检查它 User Interface 更好地了解它。

这是代码:

UISlider

非常感谢能帮助我的人,感谢您的阅读。

2 个答案:

答案 0 :(得分:1)

您的问题在于,在执行bigNumbersLaw方法期间没有布局/绘图传递。由于此方法是同步调用的,因此在自身执行之前不会进行UI更新,并且在绘制下一帧时,它将使用最新的值集。

您需要做的是将此执行“分解”为步骤,并更新它们之间的UI。

//Functions :
func bigNumbersLaw(_ liveShow: Bool, _ poss: UInt32, _ max: Double) { // #3

    if repeatNumber < max { // #1
        repeatNumber += 1
        randomNumber = arc4random_uniform(poss)
        progressBar.progress = Float(repeatNumber/max)
        if randomNumber == 1 {
            timesFound += 1
        }
        probability = (timesFound/repeatNumber)
        mainLabel.text = String(probability)
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .milliseconds(1)) {
            bigNumbersLaw(liveShow, poss, max) // #2
        }
    }
}

请记住 - 我没有测试过这段代码,但它应该可以运行。这里发生了两件大事:

  1. 对于简单的if检查,循环已更改。
  2. 此处执行“循环”。我们将在未来发送下一个“循环周期”以执行1毫秒 - 这将允许系统更新UI。
  3. 我已从代码中删除了liveShow变量,因为我找不到适合它的优雅解决方案 - 这是留给读者的练习。

    另一个注意事项 - 在执行此操作时,您应该阻止UI。

答案 1 :(得分:0)

您是否尝试过对主线程进行GUI更改?

DispatchQueue.main.async() {
   // your UI update code
}

应始终在主线程(GCD)上调用GUI的更改。这将适用于您的所有IBAction以及您希望滑块动画/移动的时间。

非常好的阅读Grand Central Dispatch - Joyce Matos on Medium