NSProgressIndicator不在El Capitan工作

时间:2015-10-13 15:55:19

标签: macos swift osx-elcapitan

我有一个OS X Swift应用程序,可以在Yosemite中正常运行,但进度条在El Capitan中没有显示。其他一切都在"真正的"程序

我创建了一个存根程序来尝试调试问题,但我仍然无法显示进度条。使用XCode 7.0.1(7A1001)并从头开始创建

测试应用程序采用计数器输入(输入)并应显示进度条,直到达到计数。如果进度条被取消隐藏,它会出现,但在结束时不会刷新,当它显示蓝色100%时。我添加了progressBar.display() - 没有效果,我对window.display()也没有效果,即没有变化。

progCount是我放在窗口上的另一个字段,看我是否可以看到数字上升,但直到最后一个数字才显示。

我使用了debug并看到i值上升,progressBar.doubleValue也增加了。它看起来像一个窗口重绘问题,但我无法找到不同的做法。请记住,这适用于约塞米蒂。

欢迎任何帮助,谢谢

---代码片段----

@IBOutlet weak var window: NSWindow!
@IBOutlet weak var progressBar: NSProgressIndicator!
@IBOutlet weak var counter: NSTextField!
@IBOutlet weak var progCount: NSTextField!

//(a bit of housekeeping not shown)

@IBAction func countUp (sender: NSButton) {
    var i=0

    if counter.integerValue != 0 {
        progressBar.hidden = false
        progressBar.minValue = 0.0
        progressBar.doubleValue = 0.0
        progressBar.maxValue = counter.doubleValue

        while i < counter.integerValue {
            i=i+1
            progressBar.incrementBy(1.0)    
            progCount.doubleValue = progressBar.doubleValue
        }
        progressBar.hidden = true

    }
}

---结束---

3 个答案:

答案 0 :(得分:2)

发现自己处于相同的情况,因为我正在从主线程上的紧密循环更新我的NSProgressIndicator。 在El Capitan之前,我只是在窗口上调用displayIfNeeded进度指示器,它运行正常。随着El Capitan的爆发,进度指标陷入0%。 虽然我同意重写我的循环以在后台线程上运行并调用主线程来更新进度指示器将是最好的解决方案,在我的情况下,遗憾的是这不是一个选项。

所以我想出的解决方法是首先在窗口上调用displayIfNeeded,然后是 [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.001]];

这使得主要的runloop有一段时间可以呼吸并且进度指示器正常前进。 是的,这是一种黑客攻击,但是在GUI应用程序的主线程上运行紧密循环。

答案 1 :(得分:0)

我无法解释为什么您的应用在Yosemite和El Capitan上的工作方式不同,但从您分享的代码的角度来看,您所描述的是其预期的行为。这是因为countUp函数中的代码会立即有效地达到最终值。这些是你可以看到的价值观。为了能够看到中间值,需要调整更新的时间。

为了说明如何观察延迟更新,可以添加延迟,如以下修改:

while i < counter.integerValue {
    i=i+1

    let delay = Double(i) * 1.0 * Double(NSEC_PER_SEC)
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

    dispatch_after(time, dispatch_get_main_queue()) {
        progressBar.incrementBy(1.0)    
        progCount.doubleValue = progressBar.doubleValue
      }
}

延迟使得第一次更新立即发生,第二次更新发生在1秒之后,第三次更新发生在第一次更新后2秒,依此类推,在主线程的串行调度队列上安排更新,适合UI更新的那个。

答案 2 :(得分:0)

尝试在进度条的编辑器中勾选“可以绘制并发”。这可能是一种解决方法,虽然它可能不是真正的解决方案。