Swift 3 - 异步显示警报控制器,并在后台运行长函数



我正在使用 Swift 3。

我正在尝试的行为是:用户单击按钮,在启动长时间运行的功能时显示旋转齿轮警报控制器。 一旦该功能完成执行,旋转的齿轮就会消失,视图控制器就会关闭。

下面的代码启动了doProcessing函数,但直到视图关闭前大约一秒钟才显示旋转齿轮。 所以这不太对。

func displaySpinningGear() {
print("display spinning gear")
// show the alert window box
let activityAlertController = UIAlertController(title: "Processing", message: "Please wait while the photo is being processed.", preferredStyle: .alert)
//create an activity indicator
let indicator = UIActivityIndicatorView(frame: activityAlertController.view.bounds)
indicator.autoresizingMask = [.flexibleWidth, .flexibleHeight]
indicator.hidesWhenStopped = true
indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
//add the activity indicator as a subview of the alert controller's view
activityAlertController.view.addSubview(indicator)
indicator.isUserInteractionEnabled = false // required otherwise if there buttons in the UIAlertController you will not be able to press them
indicator.startAnimating()
print("start animating")
self.present(activityAlertController, animated: true, completion: nil)
}
func onButtonClick() {
self.displaySpinningGear()
DispatchQueue.main.async {
self.doProcessing() // long running function
}
if let viewController = presentingViewController {
// This block will dismiss both current and a view controller presenting current
viewController.dismiss(animated: true, completion: nil)
}
else {
// This block will dismiss only current view controller
self.dismiss(animated: true, completion: nil)
}
}

下面的代码启动了doProcessing函数,但视图立即关闭,我可以从控制台上看出我的doProcessing函数仍在运行。 这也不对。

function onButtonClick() {
DispatchQueue.global(qos: .background).async {
print("Processing")
self.doProcessing() // run in background
DispatchQueue.main.async {
self.displaySpinningGear()
}
}
if let viewController = presentingViewController {
// This block will dismiss both current and a view controller presenting current
viewController.dismiss(animated: true, completion: nil)
}
else {
// This block will dismiss only current view controller
self.dismiss(animated: true, completion: nil)
}
}

如何让后台函数在显示旋转齿轮时启动,并在后台函数完成运行时(而不是之前)关闭视图和警报控制器?

编辑

尝试按照@Honey在评论中的建议将代码移动到背景块之外,但无济于事。当进程函数仍在处理时,视图会立即关闭(我可以通过打印语句判断)。

func onButtonClick() {
DispatchQueue.main.async {
self.displaySpinningGear()
}
DispatchQueue.global(qos: .background).async {
print("Processing")
self.doProcessing() // run in background
}
if let viewController = presentingViewController {
// This block will dismiss both current and a view controller presenting current
viewController.dismiss(animated: true, completion: nil)
}
else {
// This block will dismiss only current view controller
self.dismiss(animated: true, completion: nil)
}
}

从长时间运行的函数进行回调,以便在它结束时返回一个值并捕获它以消除警报。

试试吧:

typealias DoProcessingCallback = (_ finished: Bool) -> Void
func onButtonClick() {
self.displaySpinningGear()
self.doProcessing(callback: { (finished) in
if finished {
// Here you DismissViewController
// Here you DismissAlert
}
}) // long running function
}

func doProcessing(callback: DoProcessingCallback) {
// YOUR LONG CODE....
// When you know it already finished
callback(true)
}

希望对您有所帮助

我遇到了同样的问题并尝试了一堆不同的事情,这就是有效的:

activityView.alpha = 0.8
DispatchQueue.global(qos: .default).async(execute: {
DispatchQueue.main.async(execute: {
self.performSegue(withIdentifier: "cropToProcessed", sender: self)
})
})

基本上,我最初将活动指示器的alpha设置为0.0,当按下按钮时,我将其设置为0.8,然后在viewWillDisappear中将其设置回0.0,它可以工作

最新更新