[英]Alert won't dismiss (Warning: Attempt to dismiss from view controller…)
So I have a function that shows an alert while Alamofire is doing some stuff and I want to dismiss the alert when Alamofire is done but sometimes it works and sometimes it doesn't! 因此,我有一个函数可以在Alamofire正在执行某些操作时显示警报,并且我想在Alamofire完成后关闭该警报,但有时它可以工作,有时却不起作用! and when it doesn't work I'm getting the error ( iOS 13, Xcode 11 Beta 5 ): Warning: Attempt to dismiss from view controller (UITabBarController: 0x7f90b7013a00) while a presentation or dismiss is in progress!
当它不起作用时,我会收到错误消息( iOS 13,Xcode 11 Beta 5 ): 警告:在演示或关闭过程中,尝试从视图控制器(UITabBarController:0x7f90b7013a00)关闭!
This is the function I use to show the alert: 这是我用来显示警报的功能:
func showLoadingDialog(show : Bool) {
let alert = UIAlertController(title: nil, message: "⏳ Please wait...", preferredStyle: .alert)
if show == true {
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.style = .medium
loadingIndicator.startAnimating()
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
} else {
dismiss(animated: true, completion: nil)
// I've tried the "alert.dismiss" but it doesn't work!
//alert.dismiss(animated: true, completion: nil)
alert.removeFromParent()
}
}
Also I'm using tab bars and inside one of the tab bars I'm using the navigation controller and inside that I've a tableview so when the user clicks the cells it goes to another view controller (inside the same storyboard file) using this code: 另外,我在使用选项卡栏,并且在其中一个选项卡栏内使用导航控制器,并且在其中使用表格视图,因此当用户单击单元格时,它将转到使用另一个视图控制器(在同一故事板文件内部)此代码:
let detailsVC = storyboard?.instantiateViewController(identifier: "Bdetails") as? DetailsController
self.navigationController?.pushViewController(detailsVC!, animated: true)
and then I've also disabled the navigation bar (the header I guess and I'm using a custom button to return to the previews page using this code: 然后我也禁用了导航栏(我猜是标题,并且我使用自定义按钮使用以下代码返回预览页面:
self.navigationController?.popViewController(animated: true)
also here is the Alamofire where I've put the alert function and I'm using it inside viewDidLoad: 这也是Alamofire,我在其中放置了警报功能,并在viewDidLoad中使用它:
func libHttp(url: String) {
// Showing the alert.
showLoadingDialog(show: true)
Alamofire.request(url).responseJSON { (responseData) ->
Void in
if ((responseData.result.value) != nil) {
let libJSON = JSON(responseData.result.value!)
if let libData = libJSON.array {
for detail in libData {
// putting the values into an object from a custom class
}
// Updates the storyboard elements' value with the objects values.
self.update()
// dismissing the alert.
self.showLoadingDialog(show: false)
}
}
}
}
This seems like a race condition involving when you call your libHttp(url:) function. 调用libHttp(url :)函数时,这似乎是一种竞争条件。 Check for scenarios where you are dismissing the alert after you pop the viewController from the navigation controller.
从导航控制器中弹出viewController后,请检查是否有解散警报的方案。
Your showLoadingDialog(show : Bool)
looks a little strange. 您的
showLoadingDialog(show : Bool)
看起来有些奇怪。 When passing true to it, to display the alert, everything seems to be setup correctly, but when passing false, to hide the alert, you are creating a new UIAlertController
, never actually present it, and then tries to remove it. 当传递true来显示警报时,似乎一切都已正确设置,但是传递false来隐藏警报时,您正在创建一个新的
UIAlertController
,从不实际显示它,然后尝试将其删除。 I'm guessing that you really don't want to create a new UIAlertController
here, but would instead like to remove an already presented UIAlertController
? 我猜你真的不想在这里创建一个新的
UIAlertController
,而是想删除一个已经存在的UIAlertController
?
Maybe you can do something like this instead? 也许您可以执行类似的操作?
func showLoadingDialog() -> UIAlertController {
let alert = UIAlertController(title: nil, message: "⏳ Please wait...", preferredStyle: .alert)
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.style = .medium
loadingIndicator.startAnimating()
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
return alert
}
func libHttp(url: String) {
// Showing the alert.
let alert = showLoadingDialog()
Alamofire.request(url).responseJSON { (responseData) ->
Void in
if ((responseData.result.value) != nil) {
let libJSON = JSON(responseData.result.value!)
if let libData = libJSON.array {
for detail in libData {
// putting the values into an object from a custom class
}
// Updates the storyboard elements' value with the objects values.
self.update()
// dismissing the alert.
alert.dismiss(animated: true, completion: nil)
}
}
}
}
Your alert.dismiss
call isn't working because you instanciate a new AlertController each time you call the showLoadingDialog
. 您的
alert.dismiss
调用不起作用,因为每次调用showLoadingDialog
实例化一个新的showLoadingDialog
。
Here is a minimum viable working example: 这是一个最小可行的工作示例:
import UIKit
class ViewController: UIViewController {
let alert = UIAlertController(title: nil, message: "⏳ Please wait...", preferredStyle: .alert)
func showLoadingDialog(show : Bool) {
if show {
let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
loadingIndicator.hidesWhenStopped = true
loadingIndicator.style = .medium
loadingIndicator.startAnimating()
alert.view.addSubview(loadingIndicator)
present(alert, animated: true, completion: nil)
} else {
alert.dismiss(animated: true, completion: nil)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
showLoadingDialog(show: true)
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
self.showLoadingDialog(show: false)
}
}
}
Simulator Preview: 模拟器预览:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.