Свифт: Как использовать NSProgressIndicator?

Я хочу использовать NSProgressIndicator, чтобы показать некоторый прогресс. Но я не смог найти метод, который увеличивает планку этого контроля. Я также не нашел пример в Интернете.

let progressbar = NSProgressIndicator()
progressbar.frame = NSRect(x: 100, y: 20, width: 150, height: 10)
progressbar.minValue = 0
progressbar.maxValue = 10
self.window.contentView?.addSubview(progressbar)

for i in 0...10 {
    progressbar.incrementBy(1)  //has no effect
}

2 ответа

Решение

Вы не сможете продемонстрировать индикатор выполнения в таком узком цикле, как этот.

Когда вы устанавливаете значение индикатора прогресса, механизм отображения OS X на самом деле не будет рисовать разницу до следующего раза в цикле событий, что не происходит до тех пор, пока ваш метод не вернется. Другими словами, вы устанавливаете его до 10, прежде чем индикатор прогресса даже получит шанс перерисовать себя, поэтому все, что вы видите, это окончательное заполненное состояние.

Вы можете теоретически заставить индикатор прогресса отображаться после каждого циклаprogressbar.display()), но я не думаю, что вы сможете различить различия, когда они произойдут, скажем, за 0,01 секунды.

Решение в том, чтобы ввести небольшую задержку между вызовами incrementBy(1), так что может произойти следующий цикл событий и отобразится новое значение. Вы можете сделать это, добавив что-то вроде следующего в ваш код:

func delay(delay:Double, closure:()->()) {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
        Int64(delay * Double(NSEC_PER_SEC))),
                   dispatch_get_main_queue(), closure)
}

class AppDelegate: NSObject, NSApplicationDelegate {
    @IBOutlet weak var progressIndicator: NSProgressIndicator!

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        let progressbar = NSProgressIndicator()
        progressbar.frame = NSRect(x:100, y:20, width:150, height:10)
        progressbar.minValue = 0
        progressbar.maxValue = 10
        self.window.contentView?.addSubview(progressbar)

        self.progressIndicator = progressbar
        progressIndicator.indeterminate = false

        for i in 0...10 {
            delay(1.0 * Double(i), closure: { 
                self.progressIndicator.incrementBy(1)
            })
        }
    }
}

Это ставит в очередь вызов incrementBy(1) быть с интервалом в 1 секунду.

В моем случае. прогресс не получился. добавление:

      self.progress_bar.indeterminate = false;

решить проблему.

Другие вопросы по тегам