swift: activity 警报控制器后的指标
swift: activity indicator after alert controller
如果我在 alertAction 处理程序中以编程方式创建 activity 指标 - 它仅在代码完成后出现,并且如果没有 activityIndicator.stopAnimating()。为什么?我希望 activity 指标在处理耗时函数时旋转。
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)
UI 不会在您执行此操作后立即响应:
self.view.addSubview(activityIndicator)
直到下一帧才会更新UI。在这一帧和下一帧之间的时间里,你已经开始执行 time-consuming 函数并同步启动它,所以你的 UI 卡住了。执行完成后绘制下一帧。
您需要异步完成工作:
DispatchQueue.main.async {
[weak self] in
self?.timeConsumingFunc()
self?.activityIndicator.stopAnimating()
}
或者完全在不同的调度队列上。
UI 上的更改仅在它们是块时发生在主线程上。根据您的场景,您必须在主线程上异步 运行 这段代码。
DispatchQueue.main.async { [weak self] in //[weak self] is used for precaution from memory leak
self?.timeConsumingFunc()
self?.activityIndicator.stopAnimating()
}
您应该 运行 将耗时的任务放在后台队列上,然后切换回主队列以更新 UI:
DispatchQueue.global().async {
timeConsumingFunc()
DispatchQueue.main.async {
activityIndicator.stopAnimating()
}
}
您还可以使用 NVActivityIndicatorView:
来简化和改进 activity 指标
let activityData = ActivityData()
NVActivityIndicatorPresenter.sharedInstance.startAnimating(activityData)
NVActivityIndicatorPresenter.sharedInstance.setMessage("Doing stuff...")
DispatchQueue.global().async {
timeConsumingFunc()
DispatchQueue.main.async {
NVActivityIndicatorPresenter.sharedInstance.stopAnimating()
}
}
如果我在 alertAction 处理程序中以编程方式创建 activity 指标 - 它仅在代码完成后出现,并且如果没有 activityIndicator.stopAnimating()。为什么?我希望 activity 指标在处理耗时函数时旋转。
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)
UI 不会在您执行此操作后立即响应:
self.view.addSubview(activityIndicator)
直到下一帧才会更新UI。在这一帧和下一帧之间的时间里,你已经开始执行 time-consuming 函数并同步启动它,所以你的 UI 卡住了。执行完成后绘制下一帧。
您需要异步完成工作:
DispatchQueue.main.async {
[weak self] in
self?.timeConsumingFunc()
self?.activityIndicator.stopAnimating()
}
或者完全在不同的调度队列上。
UI 上的更改仅在它们是块时发生在主线程上。根据您的场景,您必须在主线程上异步 运行 这段代码。
DispatchQueue.main.async { [weak self] in //[weak self] is used for precaution from memory leak
self?.timeConsumingFunc()
self?.activityIndicator.stopAnimating()
}
您应该 运行 将耗时的任务放在后台队列上,然后切换回主队列以更新 UI:
DispatchQueue.global().async {
timeConsumingFunc()
DispatchQueue.main.async {
activityIndicator.stopAnimating()
}
}
您还可以使用 NVActivityIndicatorView:
来简化和改进 activity 指标let activityData = ActivityData()
NVActivityIndicatorPresenter.sharedInstance.startAnimating(activityData)
NVActivityIndicatorPresenter.sharedInstance.setMessage("Doing stuff...")
DispatchQueue.global().async {
timeConsumingFunc()
DispatchQueue.main.async {
NVActivityIndicatorPresenter.sharedInstance.stopAnimating()
}
}