1

I am having a NavigationController. In the ThirdViewController I am performing some task and on failure, I show Alert messages using UIAlertController.

Sometimes, when I start the task and come back to SecondViewController, I get the error message displayed on SecondViewController and on clicking OK, everything gets black below Navigation bar. I am left with only Navigation bar and if I go back again to FirstViewController, it also has the same black view except Navigation bar.

Presenting Alert of the ViewController which is not in the window hierarchy creates the issue. I do not want the Alert to be presented if I am not on the screen.

It is easily reproducible if I go back swiping the ViewController slowly.

What is the best way to handle it?

Sharing my code,

Button action in ThirdViewController

func buttonTapped() {
        APIManager.sharedManager.getDetails(completion: { (details ,error) -> Void in
            guard error == nil else {
                Alert.errorMsg(error!.localizedDescription, viewController: self, goBack: false)
                return
            }
            print(details)
        }
    }

class Alert: NSObject {

    /* Error message */
    class func errorMsg(message: String, viewController: UIViewController?, goBack: Bool = false) {
        let alertView = UIAlertController(title: "Error", message: message, preferredStyle: .Alert)
        let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { (alert: UIAlertAction) -> Void in
            if goBack == true && viewController != nil {
                viewController!.navigationController?.popToRootViewControllerAnimated(true)
            }
        }
        alertView.addAction(action)
        let controller = viewController ?? UIApplication.sharedApplication().keyWindow?.rootViewController
        controller!.presentViewController(alertView, animated: true, completion: nil)
    }
}
iOS
  • 3,526
  • 3
  • 37
  • 82

3 Answers3

3

I created a CustomViewController and added a property 'isUnloading'. In viewWillDisappear, I set isUnloading = true. I check the property before presenting the Alert.

iOS
  • 3,526
  • 3
  • 37
  • 82
0

Since you did not share any code we don't know exactly what happens there. But if you do not want to show the alert if the view controller is not in the window hierarchy you could check if viewController.view.window is set before showing the alert view and show it only if it is set.

Jelly
  • 4,522
  • 6
  • 26
  • 42
0

you can do something like,

class AlertHelper {
func showAlert(fromController controller: UIViewController) { 
    var alert = UIAlertController(title: "abc", message: "def", preferredStyle: .Alert)
    controller.presentViewController(alert, animated: true, completion: nil)
}
}

called alert as,

var alert = AlertHelper()
alert.showAlert(fromController: self)

refer this link for more detail.

Hope this will help :)

Community
  • 1
  • 1
Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75