不能从单独的功能中解除UIAlertController

时间:2017-03-28 01:45:46

标签: ios swift3 uialertcontroller dismiss

我有一个没有按钮的UIAlertController(我使用此警报,请等待一些数据加载消息),我在视图控制器的viewDidLoad函数中提供。在我发出警报后,我运行了一个从数据库中检索信息的功能,一旦完成,我想解除警报,以便用户可以继续操作,但运行后警报似乎没有解除:

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()
        }
    })
}

3 个答案:

答案 0 :(得分:2)

让我们在viewDidAppear(_:)方法中显示提醒。如果没有,您将收到错误,其视图不在窗口层次结构中!

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()
}

它正在发挥作用!

enter image description here

答案 1 :(得分:2)

在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的子类并将其添加到superview或从superview中删除时,这种方法的缺点是尝试使用警报控制器。此外,还有很多豆荚可以帮助您实现这一目标。

祝你好运, 塞吉

答案 2 :(得分:0)

是否从在不同线程上运行的数据库中检索信息的函数?如果是这样,则无法从该线程更新UI。 UI更新只能在主线程上进行。

使用此包装代码会发生什么? :)

DispatchQueue.main.async {
    alertController.dismiss(animated: false, completion: nil)
}