UIAlertController not disappearing
Asked Answered
I

5

6

I am not getting what's wrong with my code. I am simply displaying an alert with "Ok" button and when user click on "Ok", then alert should go. But its not getting disappeared. Using Swift3 for programming. Is viewDidAppear() right place to put this code? Or am I doing something wrong?

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let alertController = UIAlertController(title: "Wrong Item", message: "Could not find details of an item.", preferredStyle: .alert)          
    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
    present(alertController, animated: true, completion: nil)  
}

UPDATE: When I put the same code in other controller, it worked. In original controller, in viewDidLoad(), I have an Async call like below. Is this problem because of that?

DispatchQueue.global(qos: .background).async {
    self.getDetails(onCompletion: {(json: JSON) in

    let dict = self.convertToDictionary(text: json.stringValue)

        DispatchQueue.main.async {

            self.activityIndicator.stopAnimating()
            UIApplication.shared.endIgnoringInteractionEvents()

            //Other UI update operation

        }
    })
}    

I also override viewWillDisappear() and viewWillAppear(), just to set Title of Screen.

Importation answered 6/8, 2017 at 9:53 Comment(10)
your code is fine and correct as well as it working perfectly for meDepository
Strange. It's not working for me. :(Importation
clean and run onceDepository
:( ....still didn't workImportation
try to put in a small delay DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) { present(alertController, animated: true, completion: nil) }Journeyman
No success. Same problem. Button is not responding.Importation
@UmarFarooque Couple of things: (1) Don't put tags in the title; that's what the tags section is for. Second, if you suggest an edit, make an attempt to fix all issues in the post - or at least not just moving stuff around in the title. Thanks, and hope to see you around! :)Peppi
@Peppi Thanks for the info. Would keep that in mind.Laudanum
I updated the question with more details.Importation
if you never disable user interactions.. does it work?Ocotillo
I
1

I add below code in viewDidAppear() just before Alert code and it started working. I kept below code at both location, i.e in Async call as well as in viewDidAppear()

self.activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
Importation answered 15/8, 2017 at 19:30 Comment(0)
M
5

are you calling UIApplication.shared.beginIgnoringInteractionEvents() anywhere bro?? if yes that is your problem.

Monteiro answered 12/8, 2017 at 15:27 Comment(3)
Yes. I have it in that controller to make sure user can't click on UI while its loading. But I have UIApplication.shared.endIgnoringInteractionEvents() too to end it inside Async call in viewDidLoad(). And the alert code is in viewDidAppear()Importation
I also think this is the problem, see that you are using a queue in the background, so it has a low priority to complete. This will also complement the fact that the alert can be displayed while your activity indicator is on the screen.Overcompensation
My suggestion, (I'm assuming that you really want to read your json only in load and want the alert to be triggered whenever you display the screen, even if it is in a return) put the call to alert in a specific function and make the Call it in viewdidload after the endignoring and in the viewdidappear. Create a variable that will serve as a flag to control if the alert was called by the viewdidload and thus should not be called by the viewdidappear.Overcompensation
M
1

If we create a new "single view" project For the the following two ways of presenting the alert we get the following behaviors

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let alertController = UIAlertController(title: "Wrong Item", message: "Could not find details of an item.", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(alertController, animated: true, completion: nil)
    }

In the console you will see

2017-08-15 16:27:35.871 test[66719:7754741] Warning: Attempt to present on whose view is not in the window hierarchy!

and no alert on the UI.

and for:

   override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let alertController = UIAlertController(title: "Wrong Item", message: "Could not find details of an item.", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(alertController, animated: true, completion: nil)
    }

every thing works as expected.

So yes, view did appear is the place.

About viewDidLoad() and viewDidAppear(_:)

From the looks of it the problem lies with beginIgnoringInteractionEvents

If you are putting your alert on viewDidAppear you should see it but if you don't see it, please note the following:

Even if you put this piece of code in viewdidload

        DispatchQueue.main.async {

            self.activityIndicator.stopAnimating()
            UIApplication.shared.endIgnoringInteractionEvents()

            //Other UI update operation

        }

it may get executed later (depends on when the parsing finishes) than the call of viewDidAppear and this is because:

DispatchQueue.global(qos: .background).async

Did you check this reason?

Moreover answered 15/8, 2017 at 15:0 Comment(0)
I
1

I add below code in viewDidAppear() just before Alert code and it started working. I kept below code at both location, i.e in Async call as well as in viewDidAppear()

self.activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
Importation answered 15/8, 2017 at 19:30 Comment(0)
K
0

endIgnoringInteractionEvents() is in an async method when you click OK this method haven't been called. so you can't dismiss alert.

Krasnoyarsk answered 15/8, 2017 at 3:43 Comment(0)
H
-1

Your code looks fine, and viewDidAppear is fine as the your view controller will be loaded properly and it won't break the main thread to show you the alert. There's should be some other problem with your code, (bug of) Xcode, or derived data problem.

You can do a couple of things to see the actual problem:

  1. Clean build
  2. Delete file from Derived Data
  3. Delete App from Simulator
  4. Clean once again
  5. Restart Xcode and Simulator
  6. Rebuild to see if it works or not.
Herzberg answered 6/8, 2017 at 9:58 Comment(3)
While this helps, it's not really an answer and is probably better off as a comment on the questions helping the OP narrow down the issue.Strychninism
@Abizern, you are right, but how can I write the whole answer in a properly formatted comment? I have read so many other answers still contains only a single line suggesting any of the above thing and people accepts or upvote them as well. Here, I received a downvote for that reason.Herzberg
Couldn't get alert after moving it inside Async callImportation

© 2022 - 2024 — McMap. All rights reserved.