Warning: UIAlertController is already presenting
Solution 1
You need to change your code like this, present the second alertController on completion of dismiss. Also change your if condition with my one.
if presentedViewController == nil {
self.presentViewController(alertController, animated: true, completion: nil)
} else{
self.dismissViewControllerAnimated(false) { () -> Void in
self.presentViewController(alertController, animated: true, completion: nil)
}
}
Hope this will help you.
Solution 2
Try this
if let presented = self.presentedViewController {
presented.removeFromParentViewController()
}
if presentedViewController == nil {
self.present(alert, animated: true, completion: nil)
}
Solution 3
Try this:
[self dismissViewControllerAnimated:YES completion:nil];
UIAlertController *alertResync = [UIAlertController alertControllerWithTitle:@"Warning"
message:@"Warning Warning"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *softResyncButton = [UIAlertAction actionWithTitle:@"No, keep Some"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertAction *hardResyncButton = [UIAlertAction actionWithTitle:@"Yes"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * _Nonnull action) {
[self testFunc];
}];
[alertResync addAction:softResyncButton];
[alertResync addAction:hardResyncButton];
[self presentViewController:alertResync animated:YES completion:nil];
Solution 4
You can present another UIAlertController or anything else you want from current presented UIAlertController. Create a helper func to get top visible viewcontroller then make a present call on that
func topVisibleViewController(viewController: UIViewController) -> UIViewController? {
let viewController = viewController ?? UIApplication.shared.keyWindow?.rootViewController
if let navigationController = viewController as? UINavigationController, !navigationController.viewControllers.isEmpty {
return visibleViewController(navigationController.viewControllers.last)
}
else if let tabBarController = viewController as? UITabBarController,
let selectedController = tabBarController.selectedViewController {
return visibleViewController(selectedController)
}
else if let presentedController = viewController?.presentedViewController {
return visibleViewController(presentedController)
}
return viewController
}
CatiaV5
Updated on June 17, 2022Comments
-
CatiaV5 almost 2 years
I am a novice in swift and XCode so please forgive me the probably really messy code! When running my code I get the following warning: Warning: Attempt to present on which is already presenting
I have already checked the forum and found a post regarding that issue....I applied the help suggested as in:
if presentedViewController !== nil { self.presentViewController(alertController, animated: true, completion: nil) } else{ self.dismissViewControllerAnimated(false, completion: nil) self.presentViewController(alertController, animated: true, completion: nil) }
However, it still gives me the same warning....So I guess I must have done something wrong there. It would be great if someone could help me out please :) Also if there any suggestion as to how I can "clean" up my code are appreciated :)
import UIKit class ViewController: UIViewController { @IBOutlet var Label: UILabel! @IBOutlet var ukFlag: UITextView! @IBOutlet var movie: UITextView! @IBOutlet var piano: UITextView! @IBOutlet var book: UITextView! @IBOutlet var dance: UITextView! @IBOutlet var paint: UITextView! @IBOutlet var row: UITextView! @IBOutlet var envelope: UITextView! @IBOutlet var dragon: UITextView! @IBOutlet var instagram: UITextView! func londonPuzzle(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func misleadOne(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func bestival(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func rosieProject(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func misleadTwo(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func misleadThree(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func misleadFour(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func voucher(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func welsh(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func hulk(sender: UIPanGestureRecognizer) { let translation = sender.translationInView(self.view) sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y) sender.setTranslation(CGPointZero, inView: self.view) self.ifCollided() } func ShowAlertWrong(){ let alertController = UIAlertController(title: "Sorry", message: " Guess again!", preferredStyle: .Alert) let okAction = UIAlertAction( title: "Ok", style: UIAlertActionStyle.Default) { UIAlertAction in self.ukFlag.center = CGPointMake(150, 225) self.movie.center = CGPointMake(150, 225) self.piano.center = CGPointMake(150, 225) self.dance.center = CGPointMake(150, 225) self.paint.center = CGPointMake(150, 225) self.row.center = CGPointMake(150, 225) self.envelope.center = CGPointMake(150, 225) self.dragon.center = CGPointMake(150, 225) self.instagram.center = CGPointMake(150, 225) } let resetAction = UIAlertAction( title: "Reset", style: UIAlertActionStyle.Default) { UIALertAction in self.ukFlag.center = CGPointMake(150, 225) self.movie.center = CGPointMake(150, 225) self.piano.center = CGPointMake(150, 225) self.dance.center = CGPointMake(150, 225) self.paint.center = CGPointMake(150, 225) self.row.center = CGPointMake(150, 225) self.envelope.center = CGPointMake(150, 225) self.dragon.center = CGPointMake(150, 225) self.instagram.center = CGPointMake(150, 225) } alertController.addAction(okAction) alertController.addAction(resetAction) self.presentViewController(alertController, animated: true, completion: nil) } func ShowAlertWin(){ let alertController = UIAlertController(title: "Congrats🎉", message: " You are correct!👏🏻", preferredStyle: .Alert) let okAction = UIAlertAction( title: "Ok", style: UIAlertActionStyle.Default) { UIAlertAction in self.book.center = CGPointMake(150, 150) } /* let resetAction = UIAlertAction( title: "Reset and hope the mood has changed", style: UIAlertActionStyle.Default) { UIALertAction in self.Angry.center = CGPointMake(150, 150) }*/ alertController.addAction(okAction) // alertController.addAction(resetAction) if presentedViewController !== nil { self.presentViewController(alertController, animated: true, completion: nil) } else{ self.dismissViewControllerAnimated(false, completion: nil) self.presentViewController(alertController, animated: true, completion: nil) } } @IBAction func ifCollided(){ if CGRectIntersectsRect(Label.frame, ukFlag.frame) { ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, movie.frame){ ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, piano.frame){ ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, dance.frame){ ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, paint.frame){ ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, row.frame){ ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, envelope.frame){ ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, dragon.frame){ ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, instagram.frame){ ShowAlertWrong() } else if CGRectIntersectsRect(Label.frame, book.frame){ ShowAlertWin() } } override func viewDidLoad() { super.viewDidLoad() ukFlag.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.londonPuzzle(_:)))) movie.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.misleadOne(_:)))) piano.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.bestival(_:)))) book.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.rosieProject(_:)))) dance.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.misleadTwo(_:)))) paint.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.misleadThree(_:)))) row.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.misleadFour(_:)))) envelope.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.voucher(_:)))) dragon.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.welsh(_:)))) instagram.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.hulk(_:)))) } }
-
CatiaV5 almost 8 yearshey, thanks very much for your answer! It works however, it seems like the alert window pops up twice really quickly...I tried to fix it but I am not sure how...has it something to with it entering a loop twice or something?
-
Nirav D almost 8 yearsI don't understand what you try to say can you explain a bit more?
-
CatiaV5 almost 8 yearsif I drag drop the correct symbol on the label then the alert box opens up twice in a row in quick succession (i.e. alert "wrong" pops up shuts down and pops up again really quick). does my explanation make more sense now? it is really hard to explain...it just opens up , closes and reopens quickly
-
Nirav D almost 8 yearsCan you make some video or gif and show me so it will be helpful.
-
CatiaV5 almost 8 yearshow can I send a gif/video on here? Is it possible to private message you on here?
-
Nirav D almost 8 yearsIt is happening on wrong answer also not only correct one. I think the problem is your method is calling twice i think you can check that using
breakpoint
. Check and confirm here -
CatiaV5 almost 8 yearsThe cause seems to be "self.presentViewController(alertController, animated: true, completion: nil)" in the "else" statement. Not sure how to get around it tho.
-
Nirav D almost 8 yearsThe message is same both the times so i think you don't need to write else part, Just add the alertController, if not presented.
-
CatiaV5 almost 8 yearsyeah I have tried to use it without the else statement but this gives me the warning: "Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior"
-
Nirav D almost 8 yearsI am saying just use if condition
presentedViewController == nil
then present the controller. There is no need to write else part. -
CatiaV5 almost 8 yearsThats what I have done. I just used if presentedViewController == nil { self.presentViewController(alertController, animated: true, completion: nil)}
-
Nirav D almost 8 yearsHave you try to put break point? i think your method is calling twice.
-
CatiaV5 almost 8 yearsI am currently trying. I will let you know if I found something.
-
CatiaV5 almost 8 yearsOkay I have tried break points at several locations....without success....it seems the issue is the " else" statement...but as I said if I leave it out I will get the warning "...deallocating is not allowed..."...
-
Nirav D almost 8 yearsThat waring you should ignore check this link
-
Nirav D almost 8 yearsIt is giving you because you are not presenting the alertView after initializing. If you want to remove that error try something like this
if presentedViewController == nil {
then create the alertController instance and present it. -
CatiaV5 almost 8 yearsahhhhhh!!!! Yeah that was the problem!!! Thank you so much :) now its running perfectly fine :)
-
Dani about 6 yearsWhat if first VC is an alert? We don't want it to get automatically dismissed right away
-
Nirav D about 6 years@DaniSpringer Sorry don't get you, can you please give more details about your question ?
-
Dani about 6 yearsSure. I'm trying to show an alert view controller, and a activity view controller right after it, as soon as the alert is dismissed. Using the shown code above, the alert is shown for a moment and immediately dismissed automatically. (If you might, see last few commits for this: github.com/DaniSpringer/MemeMe1.0/blob/master/MemeMe1.0/…)
-
Nirav D about 6 years@DaniSpringer I have checked the code but what I am not getting is why you are presenting both activity indicator and alert controller one after another. That's why it might be showing alert controller on activity indicator
-
Dani about 6 yearsI want to let the user know if the image got saved. For example: they open avc, tap save, get asked permission to access photo library, and deny access. Instead of the default alert error message "data unavailable" I'd like to present a custom alert, with a human message and a link to settings app. The alert itself worked as expected, but as soon as I tried adding it to the avc, it stopped. I've updated the code a bit so if you might take another look, it might help (at least, to understand my logic 😊). Thanks!
-
user689072 over 5 yearsGreat! Update: "removeFromParentViewContoller()" is changed to "presented.removeFromParent()"