无法从单独的函数中解雇 UIAlertController
Cant Dismiss UIAlertController From Separate Function
我有一个没有按钮的 UIAlertController(我使用此警报作为请稍候一些数据加载消息),我在我的视图控制器的 viewDidLoad 函数中显示。在我提出警报后,我 运行 一个从数据库中检索信息的函数,一旦完成,我想解除警报,以便用户可以继续,但是警报似乎在 运行ning 之后没有解除:
self.dismiss(animated: true, completion: nil)
我也尝试过将我的 uialertcontroller 作为参数传递给函数,但 运行 没有成功地使用以下行:
alertController.dismiss(animated: false, completion: nil)
编辑:这是我的 viewDidLoad 函数以及应该解除警报的函数
override func viewDidLoad() {
super.viewDidLoad()
let alertController = UIAlertController(title: "Loading", message:
"This might take a moment", preferredStyle: UIAlertControllerStyle.alert)
self.present(alertController, animated: true, completion: nil)
hideAlert(alert: alertController)
}
func hideAlert(alert: UIAlertController) {
let hideAlertController = { () -> Void in
alertController.dismiss(animated: false, completion: nil)
}
FIRDatabase.database().reference().child("info").observeSingleEvent(of: .value, with: { (dataSnapshot) in
DispatchQueue.main.async {
hideAlertController()
}
})
}
从数据库 运行 检索信息的函数是否在不同的线程上?如果是这样,您无法从该线程更新 UI。 UI 更新只能发生在主线程上。
用这个包装代码会发生什么? :)
DispatchQueue.main.async {
alertController.dismiss(animated: false, completion: nil)
}
让我们在 viewDidAppear(_:)
方法中显示警报。否则,您将得到一个错误 whose view is not in the window hierarchy!:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alertController = UIAlertController(title: "Loading", message:
"This might take a moment", preferredStyle: UIAlertControllerStyle.alert)
self.present(alertController, animated: true, completion: nil)
}
func hideAlert(alert: UIAlertController) {
let hide = { () -> Void in
alert.dismiss(animated: true, completion: nil)
}
let task = URLSession.shared.dataTask(with: URL(string: "https://www.google.com/")!) { (data, response, error) in
print("error: \(error)")
DispatchQueue.main.async {
hide()
}
}
task.resume()
}
它正在运行!
在你的 ViewController 中试试这个:
var operationPerformed : Bool = false;
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning();
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad();
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated);
if(!self.operationPerformed){
let alertController = UIAlertController(title: "Loading", message:
"This might take a moment", preferredStyle: UIAlertControllerStyle.alert);
self.present(alertController, animated: true, completion: nil);
self.performOperation(alertToBeClosedOnFinish: alertController);
}
}
func performOperation(alertToBeClosedOnFinish: UIAlertController) {
let hideAlertController = { () -> Void in
alertToBeClosedOnFinish.dismiss(animated: false, completion: nil)
}
DispatchQueue.global().asyncAfter(deadline: .now() + 2, execute: {
DispatchQueue.main.async {
hideAlertController();
self.operationPerformed = true;
}
});
}
想法是当它的所有者在层次结构中时显示警报控制器,如果我理解你的意思 - 你想调用它一次,所以你应该检查操作是否已经执行。
但这种方法的缺点是当您可以将进度视图创建为 UIView 的子类并添加或删除它时尝试使用警报控制器 to/from 超级视图。此外,还有很多 pods 可以帮助您实现这一目标。
此致,
谢尔盖
我有一个没有按钮的 UIAlertController(我使用此警报作为请稍候一些数据加载消息),我在我的视图控制器的 viewDidLoad 函数中显示。在我提出警报后,我 运行 一个从数据库中检索信息的函数,一旦完成,我想解除警报,以便用户可以继续,但是警报似乎在 运行ning 之后没有解除:
self.dismiss(animated: true, completion: nil)
我也尝试过将我的 uialertcontroller 作为参数传递给函数,但 运行 没有成功地使用以下行:
alertController.dismiss(animated: false, completion: nil)
编辑:这是我的 viewDidLoad 函数以及应该解除警报的函数
override func viewDidLoad() {
super.viewDidLoad()
let alertController = UIAlertController(title: "Loading", message:
"This might take a moment", preferredStyle: UIAlertControllerStyle.alert)
self.present(alertController, animated: true, completion: nil)
hideAlert(alert: alertController)
}
func hideAlert(alert: UIAlertController) {
let hideAlertController = { () -> Void in
alertController.dismiss(animated: false, completion: nil)
}
FIRDatabase.database().reference().child("info").observeSingleEvent(of: .value, with: { (dataSnapshot) in
DispatchQueue.main.async {
hideAlertController()
}
})
}
从数据库 运行 检索信息的函数是否在不同的线程上?如果是这样,您无法从该线程更新 UI。 UI 更新只能发生在主线程上。
用这个包装代码会发生什么? :)
DispatchQueue.main.async {
alertController.dismiss(animated: false, completion: nil)
}
让我们在 viewDidAppear(_:)
方法中显示警报。否则,您将得到一个错误 whose view is not in the window hierarchy!:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alertController = UIAlertController(title: "Loading", message:
"This might take a moment", preferredStyle: UIAlertControllerStyle.alert)
self.present(alertController, animated: true, completion: nil)
}
func hideAlert(alert: UIAlertController) {
let hide = { () -> Void in
alert.dismiss(animated: true, completion: nil)
}
let task = URLSession.shared.dataTask(with: URL(string: "https://www.google.com/")!) { (data, response, error) in
print("error: \(error)")
DispatchQueue.main.async {
hide()
}
}
task.resume()
}
它正在运行!
在你的 ViewController 中试试这个:
var operationPerformed : Bool = false;
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning();
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad();
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated);
if(!self.operationPerformed){
let alertController = UIAlertController(title: "Loading", message:
"This might take a moment", preferredStyle: UIAlertControllerStyle.alert);
self.present(alertController, animated: true, completion: nil);
self.performOperation(alertToBeClosedOnFinish: alertController);
}
}
func performOperation(alertToBeClosedOnFinish: UIAlertController) {
let hideAlertController = { () -> Void in
alertToBeClosedOnFinish.dismiss(animated: false, completion: nil)
}
DispatchQueue.global().asyncAfter(deadline: .now() + 2, execute: {
DispatchQueue.main.async {
hideAlertController();
self.operationPerformed = true;
}
});
}
想法是当它的所有者在层次结构中时显示警报控制器,如果我理解你的意思 - 你想调用它一次,所以你应该检查操作是否已经执行。
但这种方法的缺点是当您可以将进度视图创建为 UIView 的子类并添加或删除它时尝试使用警报控制器 to/from 超级视图。此外,还有很多 pods 可以帮助您实现这一目标。
此致, 谢尔盖