alerts not appearing

In the following code the alert appears when I tap the alert button. The alert for missing data (bales == 0) from a text field on the same view controller as the button, does not appear.

I think this is a problem with the self.present. Self does not appear to be correct abter the checkData() fuunc is called. How do I fix this?


The error I get is

Warning: Attempt to present <UIAlertController: 0x7fc5bd801400> on <Alert_test.ViewController: 0x7fc5bad122a0> whose view is not in the window hierarchy!

TIA

Russ



import UIKit
class ViewController: UIViewController {
   
    @IBAction func showAlert(_ sender: Any) {
            showAlert1()//this shows alert
    }
    @IBOutlet weak var bales: UITextField!
    func showAlert1() {
        let alert = UIAlertController(title: "OOPS", message: "There is a problem with your data entry.", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: NSLocalizedString("FIX", comment: "Default action"), style: .default, handler: { _ in
            NSLog("The \"FIX\" alert occured.")
        }))
       self.present(alert, animated: true, completion: nil)
    }
    func checkData() {
        if bales.text == "" {
            showAlert1() //this does not show alert when bales = ""
        }}
    override func viewDidLoad() {
        super.viewDidLoad()
        checkData()
    }
Answered by russgum in 323932022

Found the problem the alert was not displaying because swift did not wait for it to display and continued to run code which at one point included a segue to another view controller which then crashed because the bad data the alert was supposed to warn about was not fixed.

I fixed that by including


DispatchQueue.main.asyncAfter(deadline: .now() + 5)


and only allowing the code to continue if a problem was found by use of else when the missing data check was triggered.

From where are you calling checkData()? Are you already in the process of dismissing (pop, unwind, whatever) that view controller at that point?

it is called from view did load. see line 21 above, but at this point the alert button is not visiable. How can I force checkData to only fire after viewDidAppear. Will that solve the problem?

If I add a button to call check data everything works.


The app that I am working on has several buttons for data entry all with error checks which should show an alert if there is a problem but only some of them show the alert.


For example only one the two @IBAction funcs linked to buttons shown below actually show the alert.

This does not work.

@IBAction func makeOrder(_ sender: AnyObject) {
        if balesToOrder.text == "" {
  let alert = UIAlertController(title: "OOPS", message: "The  number of bales in order needs to be 1 or more. ", preferredStyle: UIAlertControllerStyle.alert)
  alert.addAction(UIAlertAction(title: "Enter Bales", style: UIAlertActionStyle.default, handler: nil))
  self.present(alert, animated: true, completion: nil)
  }

This works.

@IBAction func adjustBaleCount(_ sender: AnyObject) {
  if newBales.text == "" {
            let alert = UIAlertController(title: "OOPS", message: "The adjust to number of bales needs to be 0 or more. ", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "Enter Bales", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }

Both of these are have their associated buttons on the same view. I am at a complete loss as to how to debur and fix this.

In that case, yes if you just do it from viewDidAppear, your view would be guaranteed to be in the view hierarchy. There’s also something like didMoveToParent or similar, but viewDidAppear sounds appropriate.


As for how to debug, same as any other debugging I would think... add logging, set breakpoints, make sure your methods are being called when you expect... step through line by line and see if all your variables and properties have the expected values at runtime.

Accepted Answer

Found the problem the alert was not displaying because swift did not wait for it to display and continued to run code which at one point included a segue to another view controller which then crashed because the bad data the alert was supposed to warn about was not fixed.

I fixed that by including


DispatchQueue.main.asyncAfter(deadline: .now() + 5)


and only allowing the code to continue if a problem was found by use of else when the missing data check was triggered.

alerts not appearing
 
 
Q