Попытка получить доступ к контроллеру представления, который не существует, swift 5.1 Xcode iOS - PullRequest
1 голос
/ 18 января 2020

Я работаю над приложением. когда я нажимаю на кнопку выхода из системы, она показывает мне эту ошибку Пытался открыть контроллер вида, который не существует .

вот мои экраны StoryBoard **All Screen**

**login SignUp Screen**

**profile screen with tabbar & navigationController**

вот мой AppDelegate code

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    if #available(iOS 13.0, *)
    {
    //do nothing we will have a code in SceneceDelegate for this
    }
    else {

            makeRoot()
    }
    FirebaseApp.configure()
    return true
}

func makeRoot()
{
    let defaults = UserDefaults.standard

    if defaults.bool(forKey: "isLogin") == true
    {
        let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let VC = mainStoryboard.instantiateViewController(withIdentifier: "RootTabBarC") as! RootTabBarC
        let centerNavVC = UINavigationController(rootViewController: VC)
        //centerNavVC.isNavigationBarHidden = true
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = centerNavVC
        self.window?.makeKeyAndVisible()

    }
    else
    {
        let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let VC = mainStoryboard.instantiateViewController(withIdentifier: "LoginSignUpVC") as! LoginSignUpVC
        let centerNavVC = UINavigationController(rootViewController: VC)
        //centerNavVC.isNavigationBarHidden = true
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = centerNavVC
        self.window?.makeKeyAndVisible()
    }



}

вот мой код SceneDelagate

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    guard let windowScene = (scene as? UIWindowScene) else { return }

    let defaults = UserDefaults.standard

    if defaults.bool(forKey: "isLogin") == true
    {
        //guard let windowScene = (scene as? UIWindowScene) else { return }


        self.window = UIWindow(windowScene: windowScene)
        //self.window =  UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let rootVC = storyboard.instantiateViewController(identifier: "RootTabBarC") as? RootTabBarC else {
            print("ViewController not found")
            return
        }
        let navVc = UINavigationController(rootViewController: rootVC)
        //navVc.isNavigationBarHidden = true
        self.window?.rootViewController = navVc
        self.window?.makeKeyAndVisible()
    }
    else
    {
        self.window = UIWindow(windowScene: windowScene)
        //self.window =  UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let rootVC = storyboard.instantiateViewController(identifier: "LoginSignUpVC") as? LoginSignUpVC else {
            print("ViewController not found")
            return
        }
        let navVc = UINavigationController(rootViewController: rootVC)
        //navVc.isNavigationBarHidden = true
        self.window?.rootViewController = navVc
        self.window?.makeKeyAndVisible()
    }



}

вот мой LoginSignUpV c код

import UIKit

class LoginSignUpVC: UIViewController {

@IBOutlet weak var lblTitle: UILabel!
@IBOutlet weak var btnLogin: UIButton!
@IBOutlet weak var lblDontHaveAccount: UILabel!
@IBOutlet weak var btnSignUp: UIButton!


override func viewDidLoad() {
    super.viewDidLoad()


    setupUI()
}

override func viewWillAppear(_ animated: Bool) {
    navigationController?.setNavigationBarHidden(false, animated: true)
}
override var prefersStatusBarHidden: Bool
{
    return true
}

func setupUI()
{
    letterSpacing()
    buttonSetUp()
}

@IBAction func onClickLogin(_ sender: Any)
{

}

@IBAction func onClickSignUp(_ sender: Any)
{

}

}

вот мой логинV c код

import UIKit
import FirebaseAuth

class LoginVC: UIViewController {

@IBOutlet weak var lblTitle: UILabel!
@IBOutlet weak var lblSubTitle: UILabel!
@IBOutlet weak var viewContainerEmail: UIView!
@IBOutlet weak var txtEmail: UITextField!
@IBOutlet weak var viewContainerPassword: UIView!
@IBOutlet weak var txtPassword: UITextField!
@IBOutlet weak var btnLogin: SSSpinnerButton!
@IBOutlet weak var btnForgotPassword: UIButton!


override func viewDidLoad() {
    super.viewDidLoad()

    navigationController?.navigationBar.layer.frame.origin.y = 22
    setupUI()

}

override func viewWillDisappear(_ animated: Bool) {
    btnLogin.stopAnimate(complete: nil)
}

override var prefersStatusBarHidden: Bool
{
    return true
}

func setupUI()
{
    letterSpacing()
    textFieldSetUp()
    buttonSetUp()
}

@IBAction func onClickLogin(_ sender: Any)
{
    let email = Validation.shareValidator.isValidEmail(email: txtEmail.text, view: viewContainerEmail)
    let password = Validation.shareValidator.isValidPassword(password: txtPassword.text, view: viewContainerPassword)
    if email != "success"
    {
        CustomAlert.shareAlert.alertSetUp(title: "Email Field", subTitle: email, boldTitle: "Invalid Email")
    }
    else if password != "success"
    {
        CustomAlert.shareAlert.alertSetUp(title: "Password Field", subTitle: password, boldTitle: "Invalid Password")
    }
    else
    {
        Auth.auth().signIn(withEmail: txtEmail.text!, password: txtPassword.text!) { (result, error) in
            if error != nil
            {
                CustomAlert.shareAlert.alertSetUp(title: "Login Error", subTitle: error!.localizedDescription, boldTitle: "Login Error")
            }
            else
            {
                self.btnLogin.startAnimate(spinnerType: SpinnerType.circleStrokeSpin, spinnercolor: UIColor.white, spinnerSize: 20, complete: {
                    self.btnLogin.backgroundColor = UIColor.green

                    let defaults = UserDefaults.standard

                    defaults.set(true, forKey: "isLogin")
                    defaults.set(result?.user.uid, forKey: "uid")
                    defaults.set(self.txtEmail.text!, forKey: "email")
                    //let st = UIStoryboard(name: "Main", bundle: nil)
                    let vc = self.storyboard?.instantiateViewController(withIdentifier: "RootTabBarC") as! RootTabBarC
                    self.navigationController?.pushViewController(vc, animated: true)
                })
            }
        }

    }
}

@IBAction func onClickBack(_ sender: Any)
{
    navigationController?.popViewController(animated: true)
}

}

вот мой профиль V C код

import UIKit
import FirebaseAuth
import FirebaseDatabase
import Kingfisher

class ProfileVC: UIViewController {

@IBOutlet weak var viewImageContainer: UIView!
@IBOutlet weak var imgProfile: UIImageView!
@IBOutlet weak var lblName: UILabel!
@IBOutlet weak var lblDishExpert: UILabel!
@IBOutlet weak var lblBio: UILabel!
@IBOutlet weak var imgEmailIcon: UIImageView!
@IBOutlet weak var imgPhoneIcon: UIImageView!
@IBOutlet weak var lblEmail: UILabel!
@IBOutlet weak var lblPhone: UILabel!
var userDataDict = [String]()

override func viewDidLoad() {
    super.viewDidLoad()

    setUpUI()
    showUserData()
}

@IBAction func onClickLogOut(_ sender: Any)
{
    do
    {
        try Auth.auth().signOut()

        UserDefaults.standard.set(false, forKey: "isLogin")
        UserDefaults.standard.removeObject(forKey: "uid")
        UserDefaults.standard.removeObject(forKey: "email")
        UserDefaults.standard.synchronize()

    }
    catch let err
    {
        print(err.localizedDescription)
    }


    let vc = storyboard?.instantiateViewController(identifier: "LoginSignUpVC") as? LoginSignUpVC

    navigationController?.popToViewController(vc!, animated: true)

}



}

Я также пытаюсь self.parent?.navigationController?.PopToRootViewController(animate:true), но он не работает неправильно. спасибо за вашу помощь.

Ответы [ 2 ]

1 голос
/ 18 января 2020

Когда вы впервые открываете свой экран, вы настраиваете NavigationController и добавляете login or tab Controller в соответствии с вашими функциями входа в систему. Итак, если я скажу, что я запускаю приложение, оно приведет меня к TabBar Controller, и теперь я нажимаю кнопку выхода из системы до go login Controller.

Но в стеке навигации такого контроллера нет. Поэтому я предлагаю вам снова вызвать метод сцены для настройки контроллера входа как rootController.

. Лучшее, что вы можете сделать, это сделать отдельные функции в scene class для logged in и logged out состояния.

func navigateToHomeVC(){
     self.window = UIWindow(windowScene: windowScene)
        //self.window =  UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let rootVC = storyboard.instantiateViewController(identifier: "RootTabBarC") as? RootTabBarC else {
            print("ViewController not found")
            return
        }
        let navVc = UINavigationController(rootViewController: rootVC)
        //navVc.isNavigationBarHidden = true
        self.window?.rootViewController = navVc
        self.window?.makeKeyAndVisible()
}


func navigateToLoginVC(){
      self.window = UIWindow(windowScene: windowScene)
        //self.window =  UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let rootVC = storyboard.instantiateViewController(identifier: "LoginSignUpVC") as? LoginSignUpVC else {
            print("ViewController not found")
            return
        }
        let navVc = UINavigationController(rootViewController: rootVC)
        //navVc.isNavigationBarHidden = true
        self.window?.rootViewController = navVc
        self.window?.makeKeyAndVisible()
}


func makeRoot()
{

    let defaults = UserDefaults.standard

    if defaults.bool(forKey: "isLogin") == true
    {
       navigateToHomeVC()

    }
    else{
        navigateToLoginVC()
    }
}

Теперь вызывайте эту navigateToLoginVC() функцию scene class при нажатии кнопки выхода из системы.

Надеюсь, это поможет.

0 голосов
/ 18 января 2020

Vasucd прав, сначала поместите LoginSinUpV C в viewControllers NavigationController

————— Отредактировано —————

Как показывает ошибка, это потому, что вы инициализируете новый viewController, который не существует в viewControllers NavigationController

let vc = storyboard?.instantiateViewController(identifier: "LoginSignUpVC") as? LoginSignUpVC

, чтобы решить проблему, попробуйте найти LoginSignUpV C в навигация контроллера ViewControllers view

for vc in navigationController.viewControllers {
    if let loginSignUpVC  = vc as? LoginSignUpVC {
        navigationController?.popToViewController(loginSignUpVC, animated: true)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...