swift:警报控制器后的活动指示器

时间:2018-02-24 06:59:10

标签: swift activity-indicator

如果我在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)

3 个答案:

答案 0 :(得分:2)

执行此操作后,用户界面不会立即响应:

self.view.addSubview(activityIndicator)

直到下一帧才会更新UI。在此帧和下一帧之间的时间内,您已经开始执行耗时的功能并同步启动它,因此您的UI会冻结。完成执行后绘制下一帧。

您需要异步完成工作:

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

或完全不同的调度队列。

答案 1 :(得分:1)

UI上的更改仅在主线程上发生时才是块。根据您的场景,您必须异步地在主线程上运行这段代码。

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

答案 2 :(得分:1)

您应该在后台队列上运行耗时的任务并切换回主队列以更新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()
    }
}