2015-04-24 2 views
0

Мне нужно разобрать довольно много текста и хотеть предоставить некоторую обратную связь пользователю во время этого события.UIProgressView и регулярное обновление (в Swift)

Окружающая среда Swift и, хотя я вижу код в Obj-C ([self performSelector: @selector (.....)), это не имеет большого смысла. Если бы я знал, как это сделать и внедрить в Swift-подход, я бы это сделал.

Я могу суммировать проблему с небольшим воспроизводимым случаем, дающим тот же результат. то есть в пределах цикла, увеличивать значение, показывать прогресс и возвращаться до завершения. Очевидно, что прогресс не будет показан, потому что iOS ждет, пока цикл не будет выполнен до обновления экрана.

Это имеет смысл, поэтому я хотел бы с разных интервалов прерывать обработку (т. Е. Цикл) и обновлять индикатор выполнения, прежде чем продолжить обработку.

Мой текущий код выглядит следующим образом:

@IBAction func goButton(sender: UIButton) { 
    currentCounter = 0 
    target = textTarget.text.toInt()! 
    step = textStep.text.toInt()! 
    updateProgressBar() 
    while currentCounter < target { 
     currentCounter += step 
     updateProgressBar() 
    } 
} 

func updateProgressBar() { 
    var percentage = Float(currentCounter)/Float(target) * 100 
    progressPercentage.text = "\(percentage) %" 
    println("progress = \(percentage)") 
    progressBar.setProgress(percentage, animated: false) 
} 

Я видел следующее:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
    // do some task here... 
} 
dispatch_async(dispatch_get_main_queue()) { 
    // do another task here... 
} 

Как я мог бы использовать этот подход (если это уместно), и где бы обработка против придет звонок, чтобы освежиться, если я это сделал?

Jon

ответ

3

НОД (Grand Central Dispatch), безусловно, лучший способ пойти. Это просто, мощно и интуитивно понятно, хотя вначале синтаксис может предложить другое.

Суть подхода обновления пользовательского интерфейса при выполнении трудоемкой работы всегда так:

  1. ваше приложение работает в главной очереди
  2. в какой-то момент вы хотите сделать некоторые TIME- поэтому отправляйте эту работу в какую-то очередь, отличную от основной очереди. Используйте dispatch_async с очередью, отличной от основной очереди (есть встроенные очереди, которые вы можете использовать для этого, или можете создать свой собственный)
  3. внутри этой трудоемкой работы, которую вы хотите обновить. Пользовательский интерфейс должен всегда обновляться в основной очереди, поэтому внутри этого трудоемкой части работы, вы делаете еще один dispatch_async, на этот раз используя основную очередь (есть способ получить доступ к основной очереди для этого).
  4. Внутри этого внутреннего dispatch_async вы обновляете свой интерфейс.

Для приятного и всестороннего учебного пособия по использованию GCD в контексте Swift см. this.

+0

Perfect - спасибо –

3

Вот обновленный ответ на этот вопрос с кодом, как я думаю, что другие выиграют от картины:

@IBAction func goButton(sender: UIButton) { 
    target = textTarget.text.toInt()! 
    step = textStep.text.toInt()! 
    currentCounter = 0 
    updateProgressBar() 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
     self.doTimeConsumingWork() 
    } 
} 

func doTimeConsumingWork() { 
    while currentCounter < target { 
     currentCounter += step 
     percentage = Float(currentCounter)/Float(target) * 100 

     if (percentage > 0.0) && (percentage % 10.0) == 0.0 { 
      // This is the important bit :) 
      // I chose to do this synchronously (not async) since progress updating can actually be done quite a while after the time consuming work is over 
      dispatch_sync(dispatch_get_main_queue()) { 
       self.updateProgressBar() 
      } 

     } 
    } 
    println("Finished doing time consuming work") 
} 

func updateProgressBar() { 
    progressPercentage.text = "\(percentage) %" 
    println("target = \(target), step = \(step) progress = \(percentage)") 
    progressBar.setProgress(percentage/100.0, animated: false) 
} 
+2

Поскольку Swift поддерживает операцию остатка на плавучих экземпляры точки, вы можете заменить 'если (в процентах = 10,0) || (в процентах == 20.0) || (в процентах = 30,0) || (в процентах == 40.0) || (в процентах == 50.0) || (в процентах == 60.0) || (в процентах == 70.0) || (в процентах = 80,0) || (в процентах = 90,0) || (в процентах == 100.0) {'с' if percent> 0.0 && (%% 10.0) == 0.0 {' – wltrup

Смежные вопросы