Warning: UIAlertController is already presenting

人盡茶涼 提交于 2020-01-12 07:19:07

问题


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(_:))))


}

}

回答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.




回答2:


Try this

if let presented = self.presentedViewController {
     presented.removeFromParentViewController()
  }

if presentedViewController == nil {
     self.present(alert, animated: true, completion: nil)
  }



回答3:


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
}



回答4:


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];



回答5:


I appreciate the dismissal of Alerts as mentioned in all of the answers. But I personally would never prefer dismissing something I didn't want to conjure up in the first place. Hence, if we could just look at why multiple alerts are generated in the first place, it would be awesome.

Using UIGestureRecogniser for generating UIAlert is tricky. Gestures send messages in all their underlying states. For example: if below is my code:

// Attaching LongPress to a button
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(deleteSelectedProfile(_:)))

// Method to generate appropriate alert
@objc func deleteSelectedProfile(_ sender: UILongPressGestureRecognizer) {
    let alert = UIAlertController(title: "Delete Profile", message: "Word!" , preferredStyle: .alert)
    let deleteAction = UIAlertAction(title: "Delete", style: .destructive) { (action) in
        // Code
    }
    alert.addAction(deleteAction)    
    let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
    alert.addAction(cancelAction)
    present(alert, animated: true, completion: nil)
}

UIAlert is be called upon for various states of the Gesture, starting with .began, till .ended. Hence, if clean code is what I need, I would never want to dismiss any of the alerts created at each of the states in the Gesture, rather will generate only one UIAlert. Meaning, I would simply use the State as my condition.

Hence, here is what I will change:

@objc func deleteSelectedProfile(_ sender: UILongPressGestureRecognizer) {
    if sender.state == .began {
        let alert = UIAlertController(title: "Delete Profile", message: "Word!" , preferredStyle: .alert)
        let deleteAction = ...
        alert.addAction(deleteAction)    
        let cancelAction = ...
        alert.addAction(cancelAction)
        present(alert, animated: true, completion: nil)
    }
}

This way I will be generating one alert and one alert only when required.




回答6:


This is how I debug this error in Swift 4.2:

     let alert = UIAlertController(title: "Oops!", message: "No Internet Connection", preferredStyle: .alert)
        let alertAction = UIAlertAction(title: "OK", style: .default)
        alert.addAction(alertAction)
        if let presented = self.presentedViewController {
            presented.removeFromParent()
        }

        if presentedViewController == nil {
            self.present(alert, animated: true, completion: nil)
        }       
      }


来源:https://stackoverflow.com/questions/38262593/warning-uialertcontroller-is-already-presenting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!