Search code examples
iosswiftuialertviewuialertcontroller

Why alert dismiss does not work when it is triggered again?


I show the loader before making a request to the server. After the answer is received - the function of stopping the loader is called.

The first time it works fine. But when you re-enter the page, the loader does not turn off and it remains to spin forever. (I believe this is due to the fact that the request is already happening much faster, and there is no significant delay).

For clarity, I added markers to my code.
Please tell me what the problem is and how can I fix it?

var alert : UIAlertController?

func showLoader(){
    self.alert = UIAlertController(title: nil, message: NSLocalizedString("pleaseWait", comment: "Текст ожидания загрузки"), preferredStyle: .alert)

    let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
    loadingIndicator.hidesWhenStopped = true
    loadingIndicator.style = UIActivityIndicatorView.Style.gray
    loadingIndicator.startAnimating();

    self.alert!.view.addSubview(loadingIndicator)
    present(self.alert!, animated: true, completion: nil)
    Logger.Log("Alert is presented")
}

func stopLoader(){
    if let _ = self.alert {
        Logger.Log("Loader isBeingPresented = \(self.alert!.isBeingPresented)")
        Logger.Log("Loader isBeingDismissed1 = \(self.alert!.isBeingDismissed)")

        self.alert!.dismiss(animated: false, completion: nil)

        Logger.Log("Loader isBeingDismissed2 = \(self.alert!.isBeingDismissed)")

        self.alert = nil

        Logger.Log("Loader dismissed")
    } else {
        Logger.Log("Alert failed")
    }
}

** Selected: 2019-03-01 17:00:00 +0000 ** //first try
** Alert is presented **
** File exist! **
** requestDone **
** Loader isBeingPresented = false **
** Loader isBeingDismissed1 = false **
** Loader isBeingDismissed2 = true **
** Loader dismissed **
** Selected: 2019-03-01 17:00:00 +0000 ** //second try
** Alert is presented **
** File exist! **
** requestDone **
** Loader isBeingPresented = false **
** Loader isBeingDismissed1 = false **
** Loader isBeingDismissed2 = false **
** Loader dismissed **


Solution

  • Here is how you should implement the completion blocks:

    1) viewDidLoad calls controller.start() 2) presenter calls view.showLoader() with a completion callback 3) In callback you start NetworkController.getfiles() 4) when NetworkController.getfiles() is done, controller.callback calls view.stopLoader()