【问题标题】:swift: activity indicator after alert controllerswift:警报控制器后的活动指示器
【发布时间】:2018-02-24 06:59:09
【问题描述】:

如果我在 alertAction 处理程序中以编程方式创建活动指示器 - 它仅在代码完成并且没有 activityIndi​​cator.stopAnimating() 时出现。为什么?我希望活动指示器在处理耗时的功能时旋转。

let alertController = UIAlertController(title: "Add", message: "", preferredStyle: .alert)

alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { _ in

let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
activityIndicator.color = .black
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
activityIndicator.startAnimating()
self.view.addSubview(activityIndicator)

timeConsumingFunc()

activityIndicator.stopAnimating()
}))

present(alertController, animated: true)

【问题讨论】:

    标签: swift activity-indicator


    【解决方案1】:

    执行此操作后 UI 不会立即响应:

    self.view.addSubview(activityIndicator)
    

    直到下一帧才会更新 UI。在这一帧和下一帧之间的时间里,你已经开始做耗时的功能并同步启动它,所以你的 UI 卡住了。完成执行后绘制下一帧。

    您需要异步完成工作:

    DispatchQueue.main.async {
        [weak self] in 
        self?.timeConsumingFunc()
        self?.activityIndicator.stopAnimating()
    }
    

    或完全在不同的调度队列上。

    【讨论】:

      【解决方案2】:

      UI 的变化只发生在主线程上,当它们是一个块时。根据您的情况,您必须在主线程上异步运行这段代码。

      DispatchQueue.main.async { [weak self] in //[weak self] is used for precaution from memory leak
          self?.timeConsumingFunc()
          self?.activityIndicator.stopAnimating()
      }
      

      【讨论】:

        【解决方案3】:

        您应该在后台队列上运行耗时的任务并切换回主队列以更新 UI:

        DispatchQueue.global().async {
            timeConsumingFunc()
            DispatchQueue.main.async {
                activityIndicator.stopAnimating()
            }
        }
        

        您还可以使用NVActivityIndicatorView 来简化和改进活动指示器:

        let activityData = ActivityData()
        NVActivityIndicatorPresenter.sharedInstance.startAnimating(activityData)
        NVActivityIndicatorPresenter.sharedInstance.setMessage("Doing stuff...")
        DispatchQueue.global().async {
            timeConsumingFunc()
            DispatchQueue.main.async {
                NVActivityIndicatorPresenter.sharedInstance.stopAnimating()
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-21
          • 2020-10-02
          • 2020-12-05
          相关资源
          最近更新 更多