UIAlertController, чье представление не находится в иерархии окон

Я пытаюсь создать приложение с помощью Swift и Parse. Я использую Xcode 7 и Swift 2. Я хочу показать предупреждающее сообщение, когда пользователю не удалось войти в систему, вот моя функция:

func logInViewController(logInController: PFLogInViewController, didFailToLogInWithError error: NSError?){
    let alertLoginFailed = UIAlertController(title: "Login Failed", message: "Your username or password is invalid!", preferredStyle: UIAlertControllerStyle.Alert)
    alertLoginFailed.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
    self.presentViewController(alertLoginFailed, animated: true, completion: nil)
    print("Login failed.........!")
}

Но у меня есть эта ошибка при запуске в эмуляторе:

2015-10-02 11:32:39.988 RedString[2089:886501] Warning: Attempt to present <UIAlertController: 0x7a934400> on <MyProject.ViewController: 0x7b985150> whose view is not in the window hierarchy!
Login failed.........!

Я гуглил об этом, но не нашел четкого решения.

Вот весь мой класс:

import UIKit
import Parse
import ParseUI
class ViewController: UIViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(animated: Bool) {
        self.setupLoginView()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func logInViewController(logInController: PFLogInViewController, didLogInUser user: PFUser){
        self.dismissViewControllerAnimated(true, completion: nil)
    }

    func logInViewController(logInController: PFLogInViewController, didFailToLogInWithError error: NSError?){
        let alertLoginFailed = UIAlertController(title: "Login Failed", message: "Your username or password is invalid!", preferredStyle: UIAlertControllerStyle.Alert)
        alertLoginFailed.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
        self.presentViewController(alertLoginFailed, animated: true, completion: nil)
        print("Login failed.........!")
    }

    func signUpViewController(signUpController: PFSignUpViewController, didSignUpUser user: PFUser){
        self.dismissViewControllerAnimated(true, completion: nil)
    }

    func signUpViewController(signUpController: PFSignUpViewController, didFailToSignUpWithError error: NSError?){
        print("Sign up failed.........!")
    }

    func setupLoginView(){
        if(PFUser.currentUser() == nil){
            let loginViewController = PFLogInViewController()
            loginViewController.delegate = self
            let signUpViewController = PFSignUpViewController()
            signUpViewController.delegate = self
            loginViewController.logInView!.logo = UIImageView(image: UIImage(named:"logo.png"))

            loginViewController.signUpController = signUpViewController
            self.presentViewController(loginViewController, animated: true, completion: nil)
        }else{
            print("login as: " + PFUser.currentUser()!.username!)
            //prepare new view here
        }

    }
}

person Thanh Tran    schedule 02.10.2015    source источник
comment
обратитесь к этому ответу stackoverflow .com/questions/11862883/   -  person Rizwan Shaikh    schedule 02.10.2015
comment
Может быть, это потому, что ваш viewController не отображается на экране, когда вызывается делегат loginViewController didFailToLogInWithError?   -  person Azzaknight    schedule 02.10.2015
comment
попробуйте logInContorller.presentViewController вместо self.presentViewController   -  person Azzaknight    schedule 02.10.2015


Ответы (3)


когда

func logInViewController(logInController: PFLogInViewController, didFailToLogInWithError error: NSError?){
        let alertLoginFailed = UIAlertController(title: "Login Failed", message: "Your username or password is invalid!", preferredStyle: UIAlertControllerStyle.Alert)
        alertLoginFailed.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
        self.presentViewController(alertLoginFailed, animated: true, completion: nil)
        print("Login failed.........!")
    }

вызывается, ваш контроллер представления не отображается на экране. Поэтому вы можете либо

  • отклоните logInViewController, затем отобразите предупреждение и передайте setUpLogInView в качестве обработчика.

  • или в приведенной выше функции попробуйте logInController.presentViewController вместо self.presentViewController

person Azzaknight    schedule 02.10.2015

Вы должны вызвать presentViewController:animated:completion на вашем контроллере входа в систему.

Вот упрощенная версия вашего класса, чтобы показать вам, что я имею в виду:

class ViewController: UIViewController {
    weak var loginViewController: UIViewController?

    func setupLoginViewController() {
        let loginVC = PFLogInViewController()
        // setup loginVC
        loginViewController = loginVC // store the reference
    }

    func loginDidFail() {
        let alertVC = UIAlertController(...)
        // setup alertVC
        loginViewController?.presentViewController(...) // present the alert from the login view controller
    }
}
person joern    schedule 02.10.2015
comment
Без проблем! Пожалуйста, отметьте один из ответов как принятый, чтобы этот вопрос был помечен как отвеченный. - person joern; 07.10.2015

У меня была такая же проблема в Objective-C, это происходит, когда родительское окно еще не нарисовано на экране. Я решил проблему, вызвав код из viewDidAppear, а не из viewDidLoad. См. ошибку UIAlert, чье представление не находится в иерархии окон.

person Steve    schedule 09.12.2015