【问题标题】:Attempt to present UIAlertController whose view is not in the window hierarchy (Swift 3/Xcode 8)尝试呈现其视图不在窗口层次结构中的 UIAlertController (Swift 3/Xcode 8)
【发布时间】:2017-09-10 14:39:30
【问题描述】:

我正在尝试创建一个应用程序,并且我想在出现登录错误或用户忘记输入用户名和/或密码时显示警报。但是,我总是收到此警告:

警告:尝试在 谁的视野不在窗内 等级制度!

我已经尝试了在这里找到的其他解决方案,但我仍然无法修复它。这是我的代码:

func createAlert(title: String, message: String) {

    let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)

    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in

        self.dismiss(animated: true, completion: nil)

    }))

    self.present(alert, animated: true, completion: nil)

}

@IBAction func signInPressed(_ sender: Any) {

    if usernameTextField.text == "" || passwordTextField.text == "" {

        createAlert(title: "Error in form", message: "Please enter an email and password.")

    } else {

        var activityIndicator = UIActivityIndicatorView()

        activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
        activityIndicator.center = self.view.center
        activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
        view.addSubview(activityIndicator)
        activityIndicator.startAnimating()
        UIApplication.shared.beginIgnoringInteractionEvents()

        PFUser.logInWithUsername(inBackground: usernameTextField.text!, password: passwordTextField.text!, block: { (user, error) in

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

            if error != nil {

                var displayErrorMessage = "Please try again later."

                let error = error as NSError?

                if let errorMessage = error?.userInfo["error"] as? String {

                    displayErrorMessage = errorMessage

                }

                self.createAlert(title: "Sign in error", message: displayErrorMessage)


            } else {

                print("Logged in")

                self.performSegue(withIdentifier: "toSignIn", sender: self)

            }


        })

    }

}

更新:这是整个视图控制器

class ViewController: UIViewController {

@IBOutlet var usernameTextField: UITextField!
@IBOutlet var passwordTextField: UITextField!

func createAlert(title: String, message: String) {

    let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)

    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in

        self.dismiss(animated: true, completion: nil)

    }))

    self.present(alert, animated: true, completion: nil)

}

@IBAction func signInPressed(_ sender: Any) {

    if usernameTextField.text == "" || passwordTextField.text == "" {

        createAlert(title: "Error in form", message: "Please enter an email and password.")

    } else {

        var activityIndicator = UIActivityIndicatorView()

        activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
        activityIndicator.center = self.view.center
        activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
        view.addSubview(activityIndicator)
        activityIndicator.startAnimating()
        UIApplication.shared.beginIgnoringInteractionEvents()

        PFUser.logInWithUsername(inBackground: usernameTextField.text!, password: passwordTextField.text!, block: { (user, error) in

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

            if error != nil {

                var displayErrorMessage = "Please try again later."

                let error = error as NSError?

                if let errorMessage = error?.userInfo["error"] as? String {

                    displayErrorMessage = errorMessage

                }

                self.createAlert(title: "Sign in error", message: displayErrorMessage)


            } else {

                print("Logged in")

                self.performSegue(withIdentifier: "toSignIn", sender: self)

            }


        })

    }

}

override func viewDidAppear(_ animated: Bool) {


    if PFUser.current() != nil {

        performSegue(withIdentifier: "toSignIn", sender: self)

    }

    self.tabBarController?.tabBar.isHidden = true

}

override func viewDidLoad() {
    super.viewDidLoad()

}

【问题讨论】:

  • 您可能在viewDidLoad 或其他地方调用createAlert。您能否添加您的整个视图控制器代码?
  • @PranavKasetti 我已经用整个视图控制器代码更新了我的帖子
  • 好的。您使用 segue 导航到哪个视图控制器?
  • @PranavKasetti 到标签栏控制器视图
  • 为什么self.dismiss(animated: true, completion: nil) 在你的UIAlertAction 的完成处理程序中?如果您将完成处理程序声明为 nilself 是指在此上下文中显示警报的视图控制器,则警报会自动解除,因此您不会像那样解除警报。

标签: ios swift uialertcontroller


【解决方案1】:

首先创建UIAlertController这样一个属性。

var alertController: UIAlertController?

您必须像这样在 viewDidLoad() 中添加它:

override func viewDidLoad() {
    super.viewDidLoad()

    self.alertController = UIAlertController(title: "Alert", message: "Not images yet", preferredStyle: .alert)
    self.alertController?.addAction(UIAlertAction(title: "Close", style: .default))
    view.addSubview((alertController?.view)!)

}

因此,当您按下 signInButton 并且登录不正确时,您必须调用。

@IBAction func signInPressed(_ sender: Any) {

if usernameTextField.text == "" || passwordTextField.text == "" {

    createAlert(title: "Error in form", message: "Please enter an email and password.")

} else {

    var activityIndicator = UIActivityIndicatorView()

    activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
    activityIndicator.center = self.view.center
    activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
    view.addSubview(activityIndicator)
    activityIndicator.startAnimating()
    UIApplication.shared.beginIgnoringInteractionEvents()

    PFUser.logInWithUsername(inBackground: usernameTextField.text!, password: passwordTextField.text!, block: { (user, error) in

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

        if error != nil {

            self.presentedViewController?.present(self.alertController!, animated: true, completion: nil)
        }
}

【讨论】:

    【解决方案2】:

    每当我们试图在任何闭包中呈现 UIAlertController 时,我们都应该在主线程上调用它,例如:

    DispatchQueue.main.async { [weak self] in
        self?.createAlert(title: "Sign in error", message: displayErrorMessage)
    }
    

    【讨论】:

      【解决方案3】:

      Swift 3

      试试这个代码
      func displayMyAlertMessageError(userMessage:String, titleHead: String)
          //define displyMyAlertMessage.
      {
          let MyAlert = UIAlertController(title: titleHead, message: userMessage, preferredStyle:UIAlertControllerStyle.alert);
          let okAction = UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler: nil);MyAlert.addAction(okAction);
          self.present(MyAlert,animated:true,completion:nil);
      }
      
      @IBAction func signInPressed(_ sender: Any) {
      
        if (usernameTextField.text?.isEmpty) || (passwordTextField.text?.isEmpty)
          {
            createAlert(title: "Error in form", message: "Please enter an email and password.")
          }
        else 
          {
            //Your code here
          }
      

      【讨论】:

        【解决方案4】:

        将您的 createAlert 方法更改为此,

        func createAlert(title: String, message: String, controller: UIViewController) {
        
                let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        
                alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
        
                    self.dismiss(animated: true, completion: nil)
        
                }))
                controller.present(alert, animated: true, completion: nil)
        
            }
        

        然后像这样创建警报,

        self.createAlert(title: "Sign in error", message: "Please try again later.", controller: self)
        

        这可能会解决您的问题。

        【讨论】:

        • 谢谢!但它仍然在我的调试区域显示相同的警告:(
        猜你喜欢
        • 2017-07-27
        • 2018-06-06
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 2015-06-04
        • 2020-08-07
        • 1970-01-01
        • 2016-11-29
        相关资源
        最近更新 更多