2016-01-17 4 views
1

Я пытаюсь показать spinner во время возможного длительного действия, вызванного нажатием кнопки, но я не могу заставить его отображаться. Вот мой код:UIActivityIndicatorView не отображается при вызове из действия кнопки

class ViewController: UIViewController { 

    var actInd : UIActivityIndicatorView! 
    [...] 

    override func viewDidLoad() { 

     super.viewDidLoad() 

     self.actInd = UIActivityIndicatorView(frame: CGRectMake(0,0, 50, 50)) as UIActivityIndicatorView 

     self.actInd.center = view.center 
     self.actInd.hidesWhenStopped = true 
     self.actInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray 
     self.view.addSubview(actInd) 

     [...] 
    } 

    @IBAction func buttonPressed(sender: UIBarButtonItem) { 
     self.actInd.startAnimating() 
     // [...] do some work 
     self.actInd.stopAnimating() 
    } 
} 

Он смотрит на меня как анимации не получает показанный при запуске из в потоке пользовательского интерфейса, запустившего кнопку нажатой (если я начну только анимацию в кнопку вызова без остановки, он начинает для отображения, как только закончится обратный вызов ButtonPressed). Я попытался поиграть с dispatch_async, но ничего не получил. Вот что я пробовал:

Первое:

@IBAction func buttonPressed(sender: UIBarButtonItem) { 

     dispatch_async(dispatch_get_main_queue()) { 
      self.actInd.startAnimating() 
     } 
     shufflePlaylist() 
     dispatch_async(dispatch_get_main_queue()) { 
      self.actInd.stopAnimating() 
     } 
    } 

Второе:

@IBAction func buttonPressed(sender: UIBarButtonItem) { 

     dispatch_async(dispatch_get_main_queue()) { 
      shufflePlaylist() 
     } 
    } 

    func shufflePlaylist() { 

     self.actInd.startAnimating() 
     // [...] do the work 
     self.actInd.stopAnimating() 
    } 

Третье:

@IBAction func buttonPressed(sender: UIBarButtonItem) { 

     self.actInd.startAnimating() 

     dispatch_async(dispatch_get_main_queue()) { 
      shufflePlaylist() 
     } 
    } 

    func shufflePlaylist() { 

     // [...] do the work 
     self.actInd.stopAnimating() 
    } 

Я бегу в той же проблемой при попытке показать вертушку после пользователь удаляет строку вида таблицы (которая также может инициировать некоторую длительную операцию обновления данных) в commitEditingStyle.

Итак, какой правильный подход отображать индикатор активности в этих случаях?

+0

Что именно происходит между началом и остановкой? Из того, что вы опубликовали, кажется вероятным, что счетчик запускается и немедленно останавливается, потому что вызов «сделать некоторые работы» асинхронен. Вы упомянули, что пытались использовать 'dispatch_async' - можете ли вы показать, что вы пробовали. Обычной практикой было бы отправить в рабочую очередь, выполнить требуемое действие синхронно, а затем отправить обратно в основную очередь, чтобы остановить счетчик - [этот учебник] (http://www.raywenderlich.com/79149/grand-central -dispatch-tutorial-swift-part-1) может быть полезно –

+0

«Выполнение некоторых работ» на самом деле происходит синхронно в одном потоке (он выполняет некоторые вычисления и переразбирает источник данных в виде таблицы). Я обновил свой пост тем, что я пробовал, используя 'dispatch_async' – dflachbart

ответ

0

То, что вы хотите что-то вроде:

@IBAction func buttonPressed(sender: UIBarButtonItem) { 
    spinner.startAnimating() 
    let dispatchPriority = DISPATCH_QUEUE_PRIORITY_DEFAULT 
    dispatch_async(dispatch_get_global_queue(dispatchPriority, 0)) { 

    NSThread.sleepForTimeInterval(5.0) //your task here instead of this line 

    dispatch_async(dispatch_get_main_queue(), { 
     self.spinner.stopAnimating() 
    }) 
    } 
} 

Это запускает счетчик, а затем отправляется в фоновом потоке, выполняет задачу там (я предполагаю, что задачу вы выполняете это один, который может быть выполнен на фоновом потоке, т. е. не включает в себя материал UI). По завершении задачи метод отправляется обратно в основной поток пользовательского интерфейса и останавливает счетчик.

+0

Awesome, это работает! Моя задача на самом деле делает некоторые материалы UI в конце, но я обнаружил, что могу переместить это также в отправку основной очереди, где я останавливаю счетчик. Благодаря! – dflachbart

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