我正在努力解决以下问题:
我在异步函数中启动一些网络处理:
func upload(
object: object,
context: NSManagedObjectContext
) async -> Dictionary<String,String> {
}
因此,为了通知用户一个耗时的过程刚刚开始,我会显示一个警报控制器:
let alert = UIAlertController(
title: "Loading",
message: "Please wait...",
preferredStyle: .alert
)
self.present(alert, animated: true, completion: nil)
在该功能结束时,如果一切按计划进行,我会成功关闭该警报控制器,并显示另一个警报:
alert.dismiss(
animated: true,
completion: {
let messageAlert = UIAlertController(
title: "Success",
message: "Upload complete",
preferredStyle: .alert
)
messageAlert.addAction(
UIAlertAction(
title: "OK",
style: .default,
handler: { (action: UIAlertAction) in
//
}
)
)
self.present(
messageAlert, animated: true, completion: nil
)
}
)
但我也想消除该警报并在发生错误时显示新警报,但第一个警报控制器永远不会被消除:
guard dataString.replacingOccurrences(
of: "\n",
with: ""
) != "no valid userID" else {
error = true
alert.dismiss(
animated: true,
completion: {
let messageAlert = UIAlertController(
title: "Warning",
message: "no valid userID received",
preferredStyle: .alert
)
messageAlert.addAction(
UIAlertAction(
title: "OK",
style: .default,
handler: { (action: UIAlertAction) in
//
}
)
)
self.present(
messageAlert,
animated: true,
completion: nil
)
}
)
returnDic = [
"result": "error",
"info": "no valid userID received"
]
return returnDic
}
我只是无法理解为什么我能够在该函数结束时关闭它,但不能在未来的某个地方关闭它。 Xcode 还抱怨如果现在确实正在显示一个新警报,则无法显示新警报..
[Presentation] Attempt to present <UIAlertController: 0x15880a200> on
<Project.ContainerViewController: 0x153708290> (
from <Project.LockerViewController: 0x155018200>)
while a presentation is in progress.
我已经尝试与这样的观察者合作:
var error = Bool() {
didSet {
alert.dismiss(animated: true)
}
}
它被调用,但视图不会再次被关闭:/
有什么想法吗?
我找到了解决办法: 问题是该警报控制器的呈现尚未完成,因此当时无法将其关闭。
解决此问题的方法是:
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true)
}
我通过附加一个封闭块来实现这一点
self.present(alert,animated: true) { print("alert controller is visible") }
在解雇时,该文本尚未打印出来;)
我希望这对其他人也有用;)
您还可以使用延续来等待警报的呈现和解除。
更多详情这里
extension UIViewController {
@MainActor
public func present(_ alert: UIViewController, animated: Bool) async {
await withCheckedContinuation { continuation in
present(alert, animated: animated) {
continuation.resume()
}
}
}
@MainActor
public func dismiss(animated: Bool) async {
await withCheckedContinuation { continuation in
dismiss(animated: animated) {
continuation.resume()
}
}
}
}
只需致电
await self.present(alert, animated: true)
await alert.dismiss(animated: true)