【问题标题】:UIActivityIndicatorView not showing up when invoked from button action从按钮操作调用时 UIActivityIndi​​catorView 不显示
【发布时间】:2016-01-17 18:18:43
【问题描述】:

我试图在按下按钮调用可能很长的操作期间显示一个微调器,但我无法让它显示出来。这是我的代码:

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()
    }
}

在我看来,从执行按下按钮的 UI 线程内启动时动画没有显示(如果我只在按钮调用中启动动画而不停止,它会在 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 中删除表视图行(这也可能触发一些冗长的数据更新操作)后尝试显示微调器时,我遇到了同样的问题。

那么在这些情况下显示活动指示器的正确方法是什么?

【问题讨论】:

  • start 和 stop 调用之间到底发生了什么?从您发布的内容来看,微调器似乎正在启动并立即停止,因为“做一些工作”调​​用是异步的。您提到您尝试过使用dispatch_async - 您能展示您尝试过的内容吗?通常的做法是分派到工作队列,同步执行所需的操作,然后分派回主队列以停止微调器 - this tutorial 可能会有所帮助
  • “做一些工作”实际上都是在同一个线程中同步发生的(它正在做一些计算并重新排序表视图的数据源)。我已经使用dispatch_async 尝试更新了我的帖子

标签: ios swift uiactivityindicatorview


【解决方案1】:

你想要的是这样的:

@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 内容)。任务完成后,该方法将分派回主 UI 线程,并停止微调器。

【讨论】:

  • 太棒了,这行得通!我的任务实际上是在最后做一些 UI 的东西,但我发现我也可以将它移动到我停止微调器的主队列调度中。谢谢!
猜你喜欢
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多